Fix ubsan/bounds-2.c

Submitted by Marek Polacek on June 25, 2014, 12:40 p.m.

Details

Message ID 20140625124039.GB489@redhat.com
State New
Headers show

Commit Message

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

Comments

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 hide | download patch | download mbox

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)" } */