]> 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 10:15:05 +0000 (11:15 +0100)
committerTom de Vries <tdevries@suse.de>
Thu, 13 Mar 2025 10:15:05 +0000 (11:15 +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
(cherry picked from commit 51729ea0905d1f688b7fd2ea769e69b29daa1b7c)

gdb/aarch64-tdep.c

index bc8746e27f02bf4d5dc484296b3402d18a822619..565b265ec6cb40369cbd987a3db647725943e544 100644 (file)
@@ -5200,9 +5200,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);
@@ -5265,8 +5265,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;
@@ -5337,8 +5337,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;
@@ -5350,9 +5350,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;