[binutils-gdb] asan: index out of bounds in print_insn_tic6x

Alan Modra via Binutils-cvs <[email protected]> Sun, 28 Jun 2026 10:41:31 +0000 (GMT)
Newsgroups gmane.comp.gnu.binutils.cvs
Message-ID <[email protected]>
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=1fffde7b09e14277400157785f88dcdc3b134b46

commit 1fffde7b09e14277400157785f88dcdc3b134b46
Author: Alan Modra <[email protected]>
Date:   Sun Jun 28 15:07:05 2026 +0930

    asan: index out of bounds in print_insn_tic6x
    
    header.word_compact is a seven element array.  If fp_offset has values
    of 29 to 31 then word_compact[7] is read to set num_bits which is then
    never used since the function returns before its first use.
    
            * tic6x-dis.c (print_insn_tic6x): Delay setting num_bits until
            invalid fp_offset values are handled.

Diff:
---
 opcodes/tic6x-dis.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/opcodes/tic6x-dis.c b/opcodes/tic6x-dis.c
index ca0156e21e3..eb9e1e340ea 100644
--- a/opcodes/tic6x-dis.c
+++ b/opcodes/tic6x-dis.c
@@ -264,21 +264,19 @@ print_insn_tic6x (bfd_vma addr, struct disassemble_info *info)
     {
       if (fp_offset & 0x1)
 	bad_offset = true;
-      if ((fp_offset & 0x3) && (fp_offset >= 28
-				|| !header.word_compact[fp_offset >> 2]))
+      else if ((fp_offset & 0x3) && (fp_offset >= 28
+				     || !header.word_compact[fp_offset >> 2]))
 	bad_offset = true;
-      if (fp_offset == 28)
+      else if (fp_offset == 28)
 	{
 	  info->bytes_per_chunk = 4;
 	  info->fprintf_func (info->stream, "<fetch packet header 0x%.8x>",
 			      header.header);
 	  return 4;
 	}
-      num_bits = (header.word_compact[fp_offset >> 2] ? 16 : 32);
     }
   else
     {
-      num_bits = 32;
       if (fp_offset & 0x3)
 	bad_offset = true;
     }
@@ -290,6 +288,10 @@ print_insn_tic6x (bfd_vma addr, struct disassemble_info *info)
       return 1;
     }
 
+  num_bits = 32;
+  if (fetch_packet_header_based && header.word_compact[fp_offset >> 2])
+    num_bits = 16;
+
   if (num_bits == 16)
     {
       /* The least-significant part of a 32-bit word comes logically