diff mbox

Fix -fsanitize-use-after-scope on big-endian (PR sanitizer/80308)

Message ID 20170405100137.GQ17461@tucnak
State New
Headers show

Commit Message

Jakub Jelinek April 5, 2017, 10:01 a.m. UTC
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  <jakub@redhat.com>
	    Bernd Edlinger  <bernd.edlinger@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.


	Jakub

Comments

Richard Biener April 5, 2017, 11:20 a.m. UTC | #1
On April 5, 2017 12:01:37 PM GMT+02:00, Jakub Jelinek <jakub@redhat.com> wrote:
>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?

OK.

Richard.

>2017-04-05  Jakub Jelinek  <jakub@redhat.com>
>	    Bernd Edlinger  <bernd.edlinger@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
diff mbox

Patch

--- 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;
+}