This is the mail archive of the
gdb-cvs@sourceware.org
mailing list for the GDB project.
[binutils-gdb] Fix bug in arm_push_dummy_call by -fsanitize=address
- From: Yao Qi <qiyao at sourceware dot org>
- To: gdb-cvs at sourceware dot org
- Date: 16 Nov 2015 14:45:05 -0000
- Subject: [binutils-gdb] Fix bug in arm_push_dummy_call by -fsanitize=address
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ef9bd0b8d7d0a70f9fa9b239a03099c57eb5ceea
commit ef9bd0b8d7d0a70f9fa9b239a03099c57eb5ceea
Author: Yao Qi <yao.qi@linaro.org>
Date: Mon Nov 16 14:44:19 2015 +0000
Fix bug in arm_push_dummy_call by -fsanitize=address
When I build GDB with -fsanitize=address, and run testsuite,
some gdb.base/*.exp test triggers the ERROR below,
=================================================================
==7646==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000242810 at pc 0x487844 bp 0x7fffe32e84e0 sp 0x7fffe32e84d8
READ of size 4 at 0x603000242810 thread T0
#0 0x487843 in push_stack_item /home/yao/SourceCode/gnu/gdb/git/gdb/arm-tdep.c:3405
#1 0x48998a in arm_push_dummy_call /home/yao/SourceCode/gnu/gdb/git/gdb/arm-tdep.c:3960
In that path, GDB passes value on stack, in an INT_REGISTER_SIZE slot,
but the value contents' length can be less than INT_REGISTER_SIZE, so
the contents will be accessed out of the bound. This patch adds an
array buf[INT_REGISTER_SIZE], and copy val to buf before writing them
to stack.
gdb:
2015-11-16 Yao Qi <yao.qi@linaro.org>
* arm-tdep.c (arm_push_dummy_call): New array buf. Store regval
to buf. Pass buf instead of val to push_stack_item.
Diff:
---
gdb/ChangeLog | 5 +++++
gdb/arm-tdep.c | 11 ++++++++---
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e48ffa1..2b2409a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2015-11-16 Yao Qi <yao.qi@linaro.org>
+
+ * arm-tdep.c (arm_push_dummy_call): New array buf. Store regval
+ to buf. Pass buf instead of val to push_stack_item.
+
2015-11-13 Yao Qi <yao.qi@linaro.org>
PR tdep/19051
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index b8f84ce..ef1a007 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -3925,13 +3925,13 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
while (len > 0)
{
int partial_len = len < INT_REGISTER_SIZE ? len : INT_REGISTER_SIZE;
+ CORE_ADDR regval
+ = extract_unsigned_integer (val, partial_len, byte_order);
if (may_use_core_reg && argreg <= ARM_LAST_ARG_REGNUM)
{
/* The argument is being passed in a general purpose
register. */
- CORE_ADDR regval
- = extract_unsigned_integer (val, partial_len, byte_order);
if (byte_order == BFD_ENDIAN_BIG)
regval <<= (INT_REGISTER_SIZE - partial_len) * 8;
if (arm_debug)
@@ -3945,11 +3945,16 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
}
else
{
+ gdb_byte buf[INT_REGISTER_SIZE];
+
+ memset (buf, 0, sizeof (buf));
+ store_unsigned_integer (buf, partial_len, byte_order, regval);
+
/* Push the arguments onto the stack. */
if (arm_debug)
fprintf_unfiltered (gdb_stdlog, "arg %d @ sp + %d\n",
argnum, nstack);
- si = push_stack_item (si, val, INT_REGISTER_SIZE);
+ si = push_stack_item (si, buf, INT_REGISTER_SIZE);
nstack += INT_REGISTER_SIZE;
}