Hi!

When asan unpoisons variables that don't have byte sizes that are multiples
of 8, it on big endian stores the last chunk size value into the first byte
rather than last byte, so e.g. for the variable of size 12 bytes in the
testcase it stores half-word 0x0400 into the shadow memory, which is fine
on little-endian (we want bytes 0x00 0x04), but wrong on big-endian.
We don't support asan on pdp-endian targets.

Bootstrapped/regtested on powerpc64-linux, ok for trunk?

2017-04-05  Jakub Jelinek  <ja...@redhat.com>
            Bernd Edlinger  <bernd.edlin...@hotmail.de>

        PR sanitizer/80308
        * asan.c (asan_store_shadow_bytes): Fix location of last_chunk_value
        for big endian.

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

--- gcc/asan.c.jj       2017-03-27 10:24:33.000000000 +0200
+++ gcc/asan.c  2017-04-05 08:19:00.512439980 +0200
@@ -2757,10 +2757,13 @@ asan_store_shadow_bytes (gimple_stmt_ite
 
   unsigned char c = (char) is_clobber ? ASAN_STACK_MAGIC_USE_AFTER_SCOPE : 0;
   unsigned HOST_WIDE_INT val = 0;
+  unsigned last_pos = size;
+  if (last_chunk_size && !is_clobber)
+    last_pos = BYTES_BIG_ENDIAN ? 0 : size - 1;
   for (unsigned i = 0; i < size; ++i)
     {
       unsigned char shadow_c = c;
-      if (i == size - 1 && last_chunk_size && !is_clobber)
+      if (i == last_pos)
        shadow_c = last_chunk_size;
       val |= (unsigned HOST_WIDE_INT) shadow_c << (BITS_PER_UNIT * i);
     }
--- gcc/testsuite/c-c++-common/asan/pr80308.c.jj        2017-04-05 
08:14:10.373364559 +0200
+++ gcc/testsuite/c-c++-common/asan/pr80308.c   2017-04-05 08:13:40.000000000 
+0200
@@ -0,0 +1,25 @@
+/* PR sanitizer/80308 */
+/* { dg-do run } */
+
+__attribute__((noinline, noclone)) int
+foo (char *a)
+{
+  int i, j = 0;
+  asm volatile ("" : "+r" (a) : : "memory");
+  for (i = 0; i < 12; i++)
+    j += a[i];
+  return j;
+}
+
+int
+main ()
+{
+  int i, j = 0;
+  for (i = 0; i < 4; i++)
+    {
+      char a[12];
+      __builtin_memset (a, 0, sizeof (a));
+      j += foo (a);
+    }
+  return j;
+}

        Jakub

Reply via email to