From e80944753d325ef009acf58a5b3188936997d22b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sun, 2 Dec 2018 13:39:26 +0100 Subject: [PATCH] re PR sanitizer/88291 (asan ICE in asan_clear_shadow) PR sanitizer/88291 * asan.c (asan_clear_shadow): Move assert that len is multiple of 4 to the start of the function. (asan_emit_stack_protection): When emitting clearing sequence for epilogue, align offset down to ASAN_RED_ZONE_SIZE granularity, add last_size_aligned which is last_size padded to multiples of ASAN_RED_ZONE_SIZE and emit asan_clear_shadow always on 4 byte boundaries. * c-c++-common/asan/pr88291.c: New test. From-SVN: r266721 --- gcc/ChangeLog | 11 +++++++++++ gcc/asan.c | 20 +++++++++++++------- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/c-c++-common/asan/pr88291.c | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/asan/pr88291.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c84d6fa5c25..e80e1ddd1ac 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2018-12-02 Jakub Jelinek + + PR sanitizer/88291 + * asan.c (asan_clear_shadow): Move assert that len is multiple of 4 + to the start of the function. + (asan_emit_stack_protection): When emitting clearing sequence for + epilogue, align offset down to ASAN_RED_ZONE_SIZE granularity, + add last_size_aligned which is last_size padded to multiples of + ASAN_RED_ZONE_SIZE and emit asan_clear_shadow always on 4 byte + boundaries. + 2018-12-01 Jakub Jelinek PR sanitizer/88289 diff --git a/gcc/asan.c b/gcc/asan.c index 0530ddd0056..98a42721f8f 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1165,6 +1165,7 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len) rtx_code_label *top_label; rtx end, addr, tmp; + gcc_assert ((len & 3) == 0); start_sequence (); clear_storage (shadow_mem, GEN_INT (len), BLOCK_OP_NORMAL); insns = get_insns (); @@ -1178,7 +1179,6 @@ asan_clear_shadow (rtx shadow_mem, HOST_WIDE_INT len) return; } - gcc_assert ((len & 3) == 0); top_label = gen_label_rtx (); addr = copy_to_mode_reg (Pmode, XEXP (shadow_mem, 0)); shadow_mem = adjust_automodify_address (shadow_mem, SImode, addr, 0); @@ -1375,7 +1375,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, HOST_WIDE_INT base_offset = offsets[length - 1]; HOST_WIDE_INT base_align_bias = 0, offset, prev_offset; HOST_WIDE_INT asan_frame_size = offsets[0] - base_offset; - HOST_WIDE_INT last_offset, last_size; + HOST_WIDE_INT last_offset, last_size, last_size_aligned; int l; unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT; tree str_cst, decl, id; @@ -1628,20 +1628,23 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, prev_offset = base_offset; last_offset = base_offset; last_size = 0; + last_size_aligned = 0; for (l = length; l; l -= 2) { offset = base_offset + ((offsets[l - 1] - base_offset) - & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); - if (last_offset + last_size != offset) + & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); + if (last_offset + last_size_aligned < offset) { shadow_mem = adjust_address (shadow_mem, VOIDmode, (last_offset - prev_offset) >> ASAN_SHADOW_SHIFT); prev_offset = last_offset; - asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT); + asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT); last_offset = offset; last_size = 0; } + else + last_size = offset - last_offset; last_size += base_offset + ((offsets[l - 2] - base_offset) & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1)) - offset; @@ -1667,13 +1670,16 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb, last_size += size & ~(ASAN_MIN_RED_ZONE_SIZE - HOST_WIDE_INT_1); } } + last_size_aligned + = ((last_size + (ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)) + & ~(ASAN_RED_ZONE_SIZE - HOST_WIDE_INT_1)); } - if (last_size) + if (last_size_aligned) { shadow_mem = adjust_address (shadow_mem, VOIDmode, (last_offset - prev_offset) >> ASAN_SHADOW_SHIFT); - asan_clear_shadow (shadow_mem, last_size >> ASAN_SHADOW_SHIFT); + asan_clear_shadow (shadow_mem, last_size_aligned >> ASAN_SHADOW_SHIFT); } /* Clean-up set with instrumented stack variables. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 92825b59b21..916cb5579c7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-12-02 Jakub Jelinek + PR sanitizer/88291 + * c-c++-common/asan/pr88291.c: New test. + PR c++/88258 * g++.dg/gomp/pr88258.C: New test. diff --git a/gcc/testsuite/c-c++-common/asan/pr88291.c b/gcc/testsuite/c-c++-common/asan/pr88291.c new file mode 100644 index 00000000000..e86526671d6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr88291.c @@ -0,0 +1,14 @@ +/* PR sanitizer/88291 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=address -Os" } */ +/* { dg-additional-options "-mstringop-strategy=libcall" { target i?86-*-* x86_64-*-* } } */ + +void bar (void *, void *); + +void +foo (void) +{ + int b; + char __attribute__((aligned(16))) a[(1 << 20) + 1]; + bar (&a, &b); +} -- 2.30.2