From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10827 invoked by alias); 16 Feb 2015 07:58:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 10814 invoked by uid 89); 16 Feb 2015 07:58:26 -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,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mailout4.w1.samsung.com Received: from mailout4.w1.samsung.com (HELO mailout4.w1.samsung.com) (210.118.77.14) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Mon, 16 Feb 2015 07:58:15 +0000 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0NJU004LBUBMCC60@mailout4.w1.samsung.com> for gcc-patches@gcc.gnu.org; Mon, 16 Feb 2015 08:02:10 +0000 (GMT) Received: from eusync2.samsung.com ( [203.254.199.212]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id B9.A8.07834.282A1E45; Mon, 16 Feb 2015 07:55:46 +0000 (GMT) Received: from [106.109.130.26] by eusync2.samsung.com (Oracle Communications Messaging Server 7u4-23.01(7.0.4.23.0) 64bit (built Aug 10 2011)) with ESMTPA id <0NJU00GPXU4YIP80@eusync2.samsung.com>; Mon, 16 Feb 2015 07:58:11 +0000 (GMT) Message-id: <54E194FC.2080403@partner.samsung.com> Date: Mon, 16 Feb 2015 07:58:00 -0000 From: Maxim Ostapenko User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0 MIME-version: 1.0 To: GCC Patches Cc: Yury Gribov , Slava Garbuzov Subject: [Ping] [PATCH PR64820] Fix ASan UAR detection fails on 32-bit targets if SSP is enabled. References: <54D8860A.7010903@partner.samsung.com> In-reply-to: <54D8860A.7010903@partner.samsung.com> X-Forwarded-Message-Id: <54D8860A.7010903@partner.samsung.com> Content-type: multipart/mixed; boundary=------------060005050608060106050205 X-IsSubscribed: yes X-SW-Source: 2015-02/txt/msg00928.txt.bz2 This is a multi-part message in MIME format. --------------060005050608060106050205 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1459 Ping. -------- Original Message -------- Subject: [PATCH PR64820] Fix ASan UAR detection fails on 32-bit targets if SSP is enabled. Date: Mon, 09 Feb 2015 14:03:54 +0400 From: Maxim Ostapenko To: GCC Patches CC: Yury Gribov , Slava Garbuzov Hi, when testing I noticed, that if compile with both -fsanitize=address and -fstack-protector for 32-bit architectures and run with ASAN_OPTIONS=detect_stack_use_after_return=1, libsanitizer fails with: ==7299==AddressSanitizer CHECK failed: /home/max/workspace/downloads/gcc/libsanitizer/asan/asan_poisoning.cc:25 "((AddrIsAlignedByGranularity(addr + size))) != (0)" (0x0, 0x0) #0 0xf72d8afc in AsanCheckFailed /home/max/workspace/downloads/gcc/libsanitizer/asan/asan_rtl.cc:68 #1 0xf72dda89 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) /home/max/workspace/downloads/gcc/libsanitizer/sanitizer_common/sanitizer_common.cc:72 This happens because ssp inserts a stack guard into a function, that confuses asan_emit_stack_protection to calculate right size parameter for asan_stack_malloc. This tiny patch resolves the issue. Regtested with make -j12 -k check RUNTESTFLAGS='--target_board=unix\{-m32,-m64\}' on x86_64-unknown-linux-gnu. Bootstrapped, ASan-bootstrapped on x86_64-unknown-linux-gnu. Ok to commit? -Maxim --------------060005050608060106050205 Content-Type: text/x-patch; name="ssp_asan-6.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="ssp_asan-6.diff" Content-length: 3680 gcc/ChangeLog: 2015-02-09 Max Ostapenko PR sanitizer/64820 * cfgexpand.c (align_base): New function. (alloc_stack_frame_space): Call it. (expand_stack_vars): Align prev_frame to be sure data->asan_vec elements aligned properly. gcc/testsuite/ChangeLog: 2015-02-09 Max Ostapenko PR sanitizer/64820 * c-c++-common/asan/pr64820.c: New test. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 7dfe1f6..7845a17 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -282,6 +282,15 @@ align_local_variable (tree decl) return align / BITS_PER_UNIT; } +/* Align given offset BASE with ALIGN. Truncate up if ALIGN_UP is true, + down otherwise. Return truncated BASE value. */ + +static inline unsigned HOST_WIDE_INT +align_base (HOST_WIDE_INT base, unsigned HOST_WIDE_INT align, bool align_up) +{ + return align_up ? (base + align - 1) & -align : base & -align; +} + /* Allocate SIZE bytes at byte alignment ALIGN from the stack frame. Return the frame offset. */ @@ -293,17 +302,15 @@ alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align) new_frame_offset = frame_offset; if (FRAME_GROWS_DOWNWARD) { - new_frame_offset -= size + frame_phase; - new_frame_offset &= -align; - new_frame_offset += frame_phase; + new_frame_offset + = align_base (frame_offset - frame_phase - size, + align, false) + frame_phase; offset = new_frame_offset; } else { - new_frame_offset -= frame_phase; - new_frame_offset += align - 1; - new_frame_offset &= -align; - new_frame_offset += frame_phase; + new_frame_offset + = align_base (frame_offset - frame_phase, align, true) + frame_phase; offset = new_frame_offset; new_frame_offset += size; } @@ -1031,13 +1038,16 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data) base = virtual_stack_vars_rtx; if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && pred) { - HOST_WIDE_INT prev_offset = frame_offset; + HOST_WIDE_INT prev_offset + = align_base (frame_offset, + MAX (alignb, ASAN_RED_ZONE_SIZE), + FRAME_GROWS_DOWNWARD); tree repr_decl = NULL_TREE; - offset = alloc_stack_frame_space (stack_vars[i].size + ASAN_RED_ZONE_SIZE, MAX (alignb, ASAN_RED_ZONE_SIZE)); + data->asan_vec.safe_push (prev_offset); data->asan_vec.safe_push (offset + stack_vars[i].size); /* Find best representative of the partition. diff --git a/gcc/testsuite/c-c++-common/asan/pr64820.c b/gcc/testsuite/c-c++-common/asan/pr64820.c new file mode 100644 index 0000000..885a662 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr64820.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ +/* { dg-require-effective-target fstack_protector } */ +/* { dg-options "-fstack-protector-strong" } */ +/* { dg-set-target-env-var ASAN_OPTIONS "detect_stack_use_after_return=1" } */ +/* { dg-shouldfail "asan" } */ + +__attribute__((noinline)) +char *Ident(char *x) { + return x; +} + +__attribute__((noinline)) +char *Func1() { + char local[1 << 12]; + return Ident(local); +} + +__attribute__((noinline)) +void Func2(char *x) { + *x = 1; +} +int main(int argc, char **argv) { + Func2(Func1()); + return 0; +} + +/* { dg-output "AddressSanitizer: stack-use-after-return on address 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "WRITE of size 1 at .* thread T0.*" } */ +/* { dg-output " #0.*(Func2)?.*pr64820.(c:21)?.*" } */ +/* { dg-output "is located in stack of thread T0 at offset.*" } */ --------------060005050608060106050205--