From patchwork Wed Dec 16 09:34:47 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 10028 Received: (qmail 76372 invoked by alias); 16 Dec 2015 09:35:00 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 76359 invoked by uid 89); 16 Dec 2015 09:34:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f50.google.com Received: from mail-pa0-f50.google.com (HELO mail-pa0-f50.google.com) (209.85.220.50) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 16 Dec 2015 09:34:58 +0000 Received: by mail-pa0-f50.google.com with SMTP id q3so1104624pav.3 for ; Wed, 16 Dec 2015 01:34:58 -0800 (PST) X-Received: by 10.67.7.101 with SMTP id db5mr61350036pad.53.1450258496550; Wed, 16 Dec 2015 01:34:56 -0800 (PST) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id v25sm3423829pfi.17.2015.12.16.01.34.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 16 Dec 2015 01:34:55 -0800 (PST) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH] Fix one heap buffer overflow in aarch64_push_dummy_call Date: Wed, 16 Dec 2015 09:34:47 +0000 Message-Id: <1450258487-30237-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes Hi, AddressSanitizer reports an error like this, (gdb) PASS: gdb.base/call-ar-st.exp: continue to tbreak9 print print_long_arg_list(a, b, c, d, e, f, *struct1, *struct2, *struct3, *struct4, *flags, *flags_combo, *three_char, *five_char, *int_char_combo, *d1, *d2, *d3, *f1, *f2, *f3) ================================================================= ==6236==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200008eb50 at pc 0x89e432 bp 0x7fffa3df9080 sp 0x7fffa3df9078 READ of size 5 at 0x60200008eb50 thread T0 #0 0x89e431 in memory_xfer_partial gdb/target.c:1264 #1 0x89e6c7 in target_xfer_partial gdb/target.c:1320 #2 0x89f267 in target_write_partial gdb/target.c:1595^M #3 0x8a014b in target_write_with_progress gdb/target.c:1889^M #4 0x8a0262 in target_write gdb/target.c:1914^M #5 0x89ee59 in target_write_memory gdb/target.c:1492^M #6 0x9a1c74 in write_memory gdb/corefile.c:393^M #7 0x467ea5 in aarch64_push_dummy_call gdb/aarch64-tdep.c:1388 The problem is that an instance of stack_item_t is created to adjust stack for alignment, the item.len is correct, but item.data is buf, which is wrong, because item.len can be greater than the length of buf. This patch sets item.data to NULL, and only update sp (no inferior memory writes on stack for this item). Regression tested on aarch64-linux. gdb: 2015-12-16 Yao Qi * aarch64-tdep.c (struct stack_item_t): Update comments. (pass_on_stack): Set item.data to NULL. (aarch64_push_dummy_call): Call write_memory if si->data isn't NULL. --- gdb/aarch64-tdep.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 2d1df03..f4763bb 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -855,7 +855,8 @@ aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, typedef struct { - /* Value to pass on stack. */ + /* Value to pass on stack. It can be NULL if this item is for stack + padding. */ const gdb_byte *data; /* Size in bytes of value to pass on stack. */ @@ -1124,7 +1125,7 @@ pass_on_stack (struct aarch64_call_info *info, struct type *type, int pad = align - (info->nsaa & (align - 1)); item.len = pad; - item.data = buf; + item.data = NULL; VEC_safe_push (stack_item_t, info->si, &item); info->nsaa += pad; @@ -1382,7 +1383,8 @@ aarch64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, stack_item_t *si = VEC_last (stack_item_t, info.si); sp -= si->len; - write_memory (sp, si->data, si->len); + if (si->data != NULL) + write_memory (sp, si->data, si->len); VEC_pop (stack_item_t, info.si); }