]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[gdb/record] Fix out-of-bounds write in aarch64_record_asimd_load_store
authorTom de Vries <tdevries@suse.de>
Thu, 13 Mar 2025 06:49:33 +0000 (07:49 +0100)
committerTom de Vries <tdevries@suse.de>
Thu, 13 Mar 2025 06:49:33 +0000 (07:49 +0100)
After compiling gdb with -fstack-protector-all, and running test-case
gdb.reverse/getrandom.exp on aarch64-linux, we run into
"Stack smashing detected" in function aarch64_record_asimd_load_store.

This is reported in PR record/32784.

This happens due to an out-of-bounds write to local array record_buf_mem:
...
  uint64_t record_buf_mem[24];
...
when recording insn:
...
B+>0xfffff7ff4d10  st1     {v0.16b-v3.16b}, [x0]
...

We can fix this by increasing the array size to 128, but rather than again
hardcoding a size, reimplement record_buf_mem as std::vector.

Tested on aarch64-linux.

Approved-By: Guinevere Larsen <guinevere@redhat.com>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32784

gdb/aarch64-tdep.c

index f8c9fafb229d7c31c730b34b462dce62c8741a38..bd107b8ce3af5fb03fa8c8be0085ec4729da651f 100644 (file)
@@ -5203,9 +5203,9 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
   CORE_ADDR address;
   uint64_t addr_offset = 0;
   uint32_t record_buf[24];
-  uint64_t record_buf_mem[24];
+  std::vector<uint64_t> record_buf_mem;
   uint32_t reg_rn, reg_rt;
-  uint32_t reg_index = 0, mem_index = 0;
+  uint32_t reg_index = 0;
   uint8_t opcode_bits, size_bits;
 
   reg_rt = bits (aarch64_insn_r->aarch64_insn, 0, 4);
@@ -5268,8 +5268,8 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
                record_buf[reg_index++] = reg_rt + AARCH64_V0_REGNUM;
              else
                {
-                 record_buf_mem[mem_index++] = esize / 8;
-                 record_buf_mem[mem_index++] = address + addr_offset;
+                 record_buf_mem.push_back (esize / 8);
+                 record_buf_mem.push_back (address + addr_offset);
                }
              addr_offset = addr_offset + (esize / 8);
              reg_rt = (reg_rt + 1) % 32;
@@ -5340,8 +5340,8 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
                  record_buf[reg_index++] = reg_tt + AARCH64_V0_REGNUM;
                else
                  {
-                   record_buf_mem[mem_index++] = esize / 8;
-                   record_buf_mem[mem_index++] = address + addr_offset;
+                   record_buf_mem.push_back (esize / 8);
+                   record_buf_mem.push_back (address + addr_offset);
                  }
                addr_offset = addr_offset + (esize / 8);
                reg_tt = (reg_tt + 1) % 32;
@@ -5353,9 +5353,9 @@ aarch64_record_asimd_load_store (aarch64_insn_decode_record *aarch64_insn_r)
     record_buf[reg_index++] = reg_rn;
 
   aarch64_insn_r->reg_rec_count = reg_index;
-  aarch64_insn_r->mem_rec_count = mem_index / 2;
+  aarch64_insn_r->mem_rec_count = record_buf_mem.size () / 2;
   MEM_ALLOC (aarch64_insn_r->aarch64_mems, aarch64_insn_r->mem_rec_count,
-            record_buf_mem);
+            record_buf_mem.data ());
   REG_ALLOC (aarch64_insn_r->aarch64_regs, aarch64_insn_r->reg_rec_count,
             record_buf);
   return AARCH64_RECORD_SUCCESS;