Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Commit 0735fdd

Browse files
author
Yao Qi
committed
Fix out of boundary access in pass_in_v
Hi, I build GDB with -fsanitize=address, and run testsuite. In gdb.base/callfuncs.exp, I see the following error, p t_float_values(0.0,0.0) ================================================================= ==8088==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000cb650 at pc 0x6e195c bp 0x7fff164f9770 sp 0x7fff164f9768 READ of size 16 at 0x6020000cb650 thread T0^ #0 0x6e195b in regcache_raw_write /home/yao/SourceCode/gnu/gdb/git/gdb/regcache.c:912 #1 0x6e1e52 in regcache_cooked_write /home/yao/SourceCode/gnu/gdb/git/gdb/regcache.c:945 #2 0x466d69 in pass_in_v /home/yao/SourceCode/gnu/gdb/git/gdb/aarch64-tdep.c:1101 #3 0x467512 in pass_in_v_or_stack /home/yao/SourceCode/gnu/gdb/git/gdb/aarch64-tdep.c:1196 #4 0x467d7d in aarch64_push_dummy_call /home/yao/SourceCode/gnu/gdb/git/gdb/aarch64-tdep.c:1335 The code in pass_in_v read contents from V registers (128 bit), but the data passed through V registers can be less than 128 bit. In this case, float is passed. So writing V registers contents into contents buff will cause overflow. In this patch, we add an array reg[V_REGISTER_SIZE], which is to hold the contents from V registers, and then copy useful bits to buf. gdb: 2015-11-18 Yao Qi <[email protected]> * aarch64-tdep.c (pass_in_v): Add argument len. Add local array reg. Callers updated.
1 parent 4978e36 commit 0735fdd

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

gdb/ChangeLog

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2015-11-18 Yao Qi <[email protected]>
2+
3+
* aarch64-tdep.c (pass_in_v): Add argument len. Add local array
4+
reg. Callers updated.
5+
16
2015-11-17 Yao Qi <[email protected]>
27

38
* infrun.c (resume): Check control.trap_expected only

gdb/aarch64-tdep.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -1034,17 +1034,23 @@ static int
10341034
pass_in_v (struct gdbarch *gdbarch,
10351035
struct regcache *regcache,
10361036
struct aarch64_call_info *info,
1037-
const bfd_byte *buf)
1037+
int len, const bfd_byte *buf)
10381038
{
10391039
if (info->nsrn < 8)
10401040
{
10411041
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
10421042
int regnum = AARCH64_V0_REGNUM + info->nsrn;
1043+
gdb_byte reg[V_REGISTER_SIZE];
10431044

10441045
info->argnum++;
10451046
info->nsrn++;
10461047

1047-
regcache_cooked_write (regcache, regnum, buf);
1048+
memset (reg, 0, sizeof (reg));
1049+
/* PCS C.1, the argument is allocated to the least significant
1050+
bits of V register. */
1051+
memcpy (reg, buf, len);
1052+
regcache_cooked_write (regcache, regnum, reg);
1053+
10481054
if (aarch64_debug)
10491055
{
10501056
debug_printf ("arg %d in %s\n", info->argnum,
@@ -1138,7 +1144,8 @@ pass_in_v_or_stack (struct gdbarch *gdbarch,
11381144
struct type *type,
11391145
struct value *arg)
11401146
{
1141-
if (!pass_in_v (gdbarch, regcache, info, value_contents (arg)))
1147+
if (!pass_in_v (gdbarch, regcache, info, TYPE_LENGTH (type),
1148+
value_contents (arg)))
11421149
pass_on_stack (info, type, arg);
11431150
}
11441151

@@ -1263,8 +1270,10 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
12631270
struct type *target_type =
12641271
check_typedef (TYPE_TARGET_TYPE (arg_type));
12651272

1266-
pass_in_v (gdbarch, regcache, &info, buf);
12671273
pass_in_v (gdbarch, regcache, &info,
1274+
TYPE_LENGTH (target_type), buf);
1275+
pass_in_v (gdbarch, regcache, &info,
1276+
TYPE_LENGTH (target_type),
12681277
buf + TYPE_LENGTH (target_type));
12691278
}
12701279
else

0 commit comments

Comments
 (0)