Patchwork Fix ubsan/bounds-2.c

login
register
mail settings
Submitter Marek Polacek
Date June 25, 2014, 12:40 p.m.
Message ID <20140625124039.GB489@redhat.com>
Download mbox | patch
Permalink /patch/363991/
State New
Headers show

Comments

Marek Polacek - June 25, 2014, 12:40 p.m.
On IRC Ramana reported that on ARM ubsan/bounds-2.c test fails with -O0,
since we write to out-of-bounds location and probably rewrite the
frame pointer stored in the stack.  This patch removes such stores
and adds some asm magic so the compiler doesn't optimize loads away as
uninitialized memory read.

Ramana, does this patch help on ARM?
Tested x86_64-unknown-linux-gnu, ok for trunk?

2014-06-25  Marek Polacek  <polacek@redhat.com>

	* c-c++-common/ubsan/bounds-2.c: Adjust dg-output.
	(fn1): Remove store to out-of-bounds location.  Add memory barrier.
	(fn2): Likewise.
	(fn5): Likewise.
	(fn6): Likewise.
	(fn7): Likewise.
	(fn8): Likewise.
	(fn9): Likewise.
	(fn11): Likewise.


	Marek
Jakub Jelinek - June 25, 2014, 12:49 p.m.
On Wed, Jun 25, 2014 at 02:40:40PM +0200, Marek Polacek wrote:
> On IRC Ramana reported that on ARM ubsan/bounds-2.c test fails with -O0,
> since we write to out-of-bounds location and probably rewrite the
> frame pointer stored in the stack.  This patch removes such stores
> and adds some asm magic so the compiler doesn't optimize loads away as
> uninitialized memory read.
> 
> Ramana, does this patch help on ARM?
> Tested x86_64-unknown-linux-gnu, ok for trunk?

What about bounds-5.c ?  Also, do you have any tests for negative indexes?

	Jakub

Patch

diff --git gcc/testsuite/c-c++-common/ubsan/bounds-2.c gcc/testsuite/c-c++-common/ubsan/bounds-2.c
index 95f77c2..3a24d40 100644
--- gcc/testsuite/c-c++-common/ubsan/bounds-2.c
+++ gcc/testsuite/c-c++-common/ubsan/bounds-2.c
@@ -22,7 +22,7 @@  static void __attribute__ ((noinline, noclone))
 fn1 (void)
 {
   volatile int a[5];
-  a[5] = 1;
+  asm ("" : : "r" (&a[5]) : "memory");
   a[2] = a[5];
 }
 
@@ -30,9 +30,11 @@  static void __attribute__ ((noinline, noclone))
 fn2 (void)
 {
   volatile int a[5];
+  volatile int j;
   int i = 5;
   int *p = &i;
-  a[*p] = 1;
+  asm ("" : : "r" (&a[*p]) : "memory");
+  j = a[*p];
 }
 
 static void __attribute__ ((noinline, noclone))
@@ -54,7 +56,7 @@  fn5 (void)
 {
   int i = 5;
   volatile int a[i];
-  a[i] = 1;
+  asm ("" : : "r" (&a[i]) : "memory");
   a[2] = a[i];
 }
 
@@ -63,29 +65,32 @@  fn6 (void)
 {
   int i = 5;
   volatile int a[i];
+  volatile int j;
   fn_p (a[i]);
-  a[foo_5 ()] = 1;
+  asm ("" : : "r" (&a[foo_5 ()]) : "memory");
+  j = a[foo_5 ()];
 }
 
 static void __attribute__ ((noinline, noclone))
 fn7 (void)
 {
-  int n = 5, i;
+  int n = 5;
+  volatile int i;
   volatile int c[n][n][n];
-  c[5][2][2] = 2;
-  c[2][5][2] = 2;
-  c[2][2][5] = 2;
+  asm ("" : : "r" (&c[5][2][2]) : "memory");
   i = c[5][2][2];
+  asm ("" : : "r" (&c[2][5][2]) : "memory");
   i = c[2][5][2];
+  asm ("" : : "r" (&c[2][2][5]) : "memory");
   i = c[2][2][5];
 }
 
 static void __attribute__ ((noinline, noclone))
 fn8 (void)
 {
-  int i = 5;
+  volatile int i;
   volatile struct S s;
-  s.a[10] = 1;
+  asm ("" : : "r" (&s.a[10]) : "memory");
   i = s.a[10];
 }
 
@@ -93,7 +98,7 @@  static void __attribute__ ((noinline, noclone))
 fn9 (void)
 {
   long int *volatile d[10][5];
-  d[10][0] = 0;
+  asm ("" : : "r" (&d[10][0]) : "memory");
   d[8][3] = d[10][0];
 }
 
@@ -115,7 +120,7 @@  static void __attribute__ ((noinline, noclone))
 fn11 (void)
 {
   char ***volatile f[5];
-  f[5] = 0;
+  asm ("" : : "r" (&f[5]) : "memory");
   f[2] = f[5];
 }
 
@@ -148,21 +153,16 @@  main (void)
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]\\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[10\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 10 out of bounds for type 'int \\\[10\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 10 out of bounds for type 'long int \\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 10 out of bounds for type 'long int \\\*\\\[10\\\]\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'char \\\*\\\*\\\*\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output "\[^\n\r]*index 5 out of bounds for type 'char \\\*\\\*\\\*\\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
 /* { dg-output "\[^\n\r]*index 5 out of bounds for type 'int \\\[5\\\]'\[^\n\r]*(\n|\r\n|\r)" } */