diff options
author | Tom de Vries <tdevries@suse.de> | 2025-03-13 07:49:33 +0100 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2025-03-13 07:49:33 +0100 |
commit | 51729ea0905d1f688b7fd2ea769e69b29daa1b7c (patch) | |
tree | 275b0b814fdf6896da6b3f0775af1324ea434835 | |
parent | f9f033220046f011aeb259469cb15fe8141b213b (diff) | |
download | binutils-51729ea0905d1f688b7fd2ea769e69b29daa1b7c.zip binutils-51729ea0905d1f688b7fd2ea769e69b29daa1b7c.tar.gz binutils-51729ea0905d1f688b7fd2ea769e69b29daa1b7c.tar.bz2 |
[gdb/record] Fix out-of-bounds write in aarch64_record_asimd_load_store
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
-rw-r--r-- | gdb/aarch64-tdep.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index f8c9faf..bd107b8 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -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; |