From: Max Ostapenko Date: Tue, 8 Dec 2015 11:34:28 +0000 (+0200) Subject: backport: re PR sanitizer/64820 (Libsanitizer fails with ((AddrIsAlignedByGranularity... X-Git-Tag: releases/gcc-4.9.4~463 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8396f2831845fc1d0ad9bf7c1ff6f9fb6b0e3638;p=thirdparty%2Fgcc.git backport: re PR sanitizer/64820 (Libsanitizer fails with ((AddrIsAlignedByGranularity(addr + size))) != (0)" (0x0, 0x0) if ssp is enabled.) 2015-12-08 Maxim Ostapenko Backport from mainline. 2015-03-16 Max Ostapenko PR sanitizer/64820 gcc/ * 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/ * c-c++-common/asan/pr64820.c: New test. From-SVN: r231405 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index de5c0bdaa1e0..a0e5e2a8b54e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2015-12-08 Maxim Ostapenko + + Backport from mainline. + 2015-03-16 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. + 2015-12-04 Andreas Tobler Backport from mainline diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 14511e137aa4..8bebd85b1c74 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -248,6 +248,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. */ @@ -256,20 +265,17 @@ alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align) { HOST_WIDE_INT offset, new_frame_offset; - 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; } @@ -983,13 +989,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/ChangeLog b/gcc/testsuite/ChangeLog index 04a355bcd176..92dca2ebaf91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2015-12-08 Maxim Ostapenko + + Backport from mainline. + 2015-03-16 Max Ostapenko + + PR sanitizer/64820 + * c-c++-common/asan/pr64820.c: New test. + 2015-11-27 Andre Vehreschild PR fortran/68218 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 000000000000..885a66214917 --- /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.*" } */ +/* { dg-output "\'local\' <== Memory access at offset 32 is inside this variable" } */