Hi!

As the testcase below shows, -fsanitize=address has issues with
correspondence of actual layout of vars in the stack (or heap) frame and
what regions are considered to be pads (and which kind), if there are
variables aligned to more than ASAN_RED_ZONE_SIZE (32 bytes).

The bug is in a typo, the intent in align_base call in expand_stack_vars
is to match what alloc_stack_frame_space is doing (assuming frame_phase of
0), but that function has:
  if (FRAME_GROWS_DOWNWARD)
    {
      ... align_base (..., false) ...
    }
  else
    {
      ... align_base (..., true) ...
    }
so we need to pass !FRAME_GROWS_DOWNWARD instead of FRAME_GROWS_DOWNWARD.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk as
obvious, will backport to branches after 6.1 goes out.

2016-04-23  Jakub Jelinek  <ja...@redhat.com>

        PR sanitizer/70712
        * cfgexpand.c (expand_stack_vars): Fix typo.

        * c-c++-common/asan/pr70712.c: New test.

--- gcc/cfgexpand.c.jj  2016-04-22 18:21:52.000000000 +0200
+++ gcc/cfgexpand.c     2016-04-22 18:35:02.129325661 +0200
@@ -1137,7 +1137,7 @@ expand_stack_vars (bool (*pred) (size_t)
              HOST_WIDE_INT prev_offset
                = align_base (frame_offset,
                              MAX (alignb, ASAN_RED_ZONE_SIZE),
-                             FRAME_GROWS_DOWNWARD);
+                             !FRAME_GROWS_DOWNWARD);
              tree repr_decl = NULL_TREE;
              offset
                = alloc_stack_frame_space (stack_vars[i].size
--- gcc/testsuite/c-c++-common/asan/pr70712.c.jj        2016-04-22 
18:30:45.246786590 +0200
+++ gcc/testsuite/c-c++-common/asan/pr70712.c   2016-04-22 18:30:30.000000000 
+0200
@@ -0,0 +1,32 @@
+/* PR sanitizer/70712 */
+/* { dg-do run } */
+
+struct __attribute__((aligned (64))) S
+{
+  char s[4];
+};
+
+struct T
+{
+  char t[8];
+  char u[480];
+
+};
+
+__attribute__((noinline, noclone)) void
+foo (struct T *p, struct S *q)
+{
+  __builtin_memset (p->t, '\0', sizeof (p->t));
+  __builtin_memset (p->u, '\0', sizeof (p->u));
+  __builtin_memset (q->s, '\0', sizeof (q->s));
+}
+
+int
+main ()
+{
+  struct S s;
+  struct T t;
+  foo (&t, &s);
+  asm volatile ("" : : "r" (&t), "r" (&s) : "memory");
+  return 0;
+}

        Jakub

Reply via email to