PR sanitizer/88291 81/210381/3
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 2 Dec 2018 12:39:26 +0000 (12:39 +0000)
committerDongkyun Son <dongkyun.s@samsung.com>
Mon, 22 Jul 2019 11:57:12 +0000 (11:57 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@266721 138bc75d-0d04-0410-961f-82ee72b054a4

(cherry picked b0d945ba743397d845ab6bc3c3834241f28bb91f)

Change-Id: I8a86e9d61617253e8439ca2c5659a2436604d30b

gcc/ChangeLog
gcc/asan.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/pr88291.c [new file with mode: 0644]

index 2dd219f..8c0d502 100644 (file)
@@ -1,3 +1,14 @@
+2018-12-02  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <jakub@redhat.com>
        PR sanitizer/88289
        * asan.c (asan_redzone_buffer::flush_redzone_payload): Fix up
index 3a20723..813e97b 100644 (file)
@@ -983,6 +983,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 ();
@@ -996,7 +997,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);
@@ -1191,7 +1191,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;
@@ -1444,20 +1444,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;
@@ -1483,13 +1486,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.  */
index 1e59222..2e6c35b 100644 (file)
@@ -1,3 +1,14 @@
+2018-12-02  Jakub Jelinek  <jakub@redhat.com>
+
+       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-11-30  Martin Liska  <mliska@suse.cz>
 
        PR sanitizer/81715
diff --git a/gcc/testsuite/c-c++-common/asan/pr88291.c b/gcc/testsuite/c-c++-common/asan/pr88291.c
new file mode 100644 (file)
index 0000000..e865266
--- /dev/null
@@ -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);
+}