re PR sanitizer/65280 (-fsanitize=bounds does not detect out-of-bounds access)
authorMarek Polacek <polacek@redhat.com>
Fri, 6 Mar 2015 23:44:56 +0000 (23:44 +0000)
committerMarek Polacek <mpolacek@gcc.gnu.org>
Fri, 6 Mar 2015 23:44:56 +0000 (23:44 +0000)
PR sanitizer/65280
* doc/invoke.texi: Update description of -fsanitize=bounds.

* c-ubsan.c (ubsan_instrument_bounds): Check for COMPONENT_REF
before trying to figure out whether we have a flexible array member.

* c-c++-common/ubsan/bounds-1.c: Add testing of flexible array
member-like arrays.
* c-c++-common/ubsan/bounds-8.c: New test.
* c-c++-common/ubsan/bounds-9.c: New test.
* gcc.dg/ubsan/bounds-2.c: New test.

Co-Authored-By: Martin Uecker <uecker@eecs.berkeley.edu>
From-SVN: r221250

gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-ubsan.c
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/ubsan/bounds-1.c
gcc/testsuite/c-c++-common/ubsan/bounds-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/ubsan/bounds-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ubsan/bounds-2.c [new file with mode: 0644]

index 3b7801ed54acd50905cbca082a7cf5891d23cb56..f71958d88664cc945d61971b9ed482f73aa42da8 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-07  Marek Polacek  <polacek@redhat.com>
+           Martin Uecker  <uecker@eecs.berkeley.edu>
+
+       PR sanitizer/65280
+       * doc/invoke.texi: Update description of -fsanitize=bounds.
+
 2015-03-06  Wilco Dijkstra  <wilco.dijkstra@arm.com>
 
        * tree-ssa-phiopt.c (neg_replacement): Remove.
index fa08958ac6cdea11f8a4b13f694da73c4b23ff46..6bd5a28fa8bdc383573012f1749a2058d3bbc2bd 100644 (file)
@@ -1,3 +1,9 @@
+2015-03-07  Marek Polacek  <polacek@redhat.com>
+
+       PR sanitizer/65280
+       * c-ubsan.c (ubsan_instrument_bounds): Check for COMPONENT_REF
+       before trying to figure out whether we have a flexible array member.
+
 2015-03-06  Eric Botcazou  <ebotcazou@adacore.com>
             Jonathan Wakely  <jwakely.gcc@gmail.com>
 
index 90d59c03a1609be63f601003153ccd63db61f612..a14426f962467aa5148be765cfe89383cfbe8ef5 100644 (file)
@@ -303,8 +303,9 @@ ubsan_instrument_bounds (location_t loc, tree array, tree *index,
 
   /* Detect flexible array members and suchlike.  */
   tree base = get_base_address (array);
-  if (base && (TREE_CODE (base) == INDIRECT_REF
-              || TREE_CODE (base) == MEM_REF))
+  if (TREE_CODE (array) == COMPONENT_REF
+      && base && (TREE_CODE (base) == INDIRECT_REF
+                 || TREE_CODE (base) == MEM_REF))
     {
       tree next = NULL_TREE;
       tree cref = array;
index 006a852af190fd294a30dfdc5d8e735f9ff4f1ec..67814d40d5fd8f33cbc96a04ef519ad832e3de0c 100644 (file)
@@ -5704,8 +5704,8 @@ a++;
 @item -fsanitize=bounds
 @opindex fsanitize=bounds
 This option enables instrumentation of array bounds.  Various out of bounds
-accesses are detected.  Flexible array members and initializers of variables
-with static storage are not instrumented.
+accesses are detected.  Flexible array members, flexible array member-like
+arrays, and initializers of variables with static storage are not instrumented.
 
 @item -fsanitize=alignment
 @opindex fsanitize=alignment
index 702e06bad09baceb7e0df3cd18f198afe5fddd6c..0a9c561c1aebe0c84f2942ec2620a8211f500e33 100644 (file)
@@ -1,3 +1,13 @@
+2015-03-07  Marek Polacek  <polacek@redhat.com>
+           Martin Uecker  <uecker@eecs.berkeley.edu>
+
+       PR sanitizer/65280
+       * c-c++-common/ubsan/bounds-1.c: Add testing of flexible array
+       member-like arrays.
+       * c-c++-common/ubsan/bounds-8.c: New test.
+       * c-c++-common/ubsan/bounds-9.c: New test.
+       * gcc.dg/ubsan/bounds-2.c: New test.
+
 2015-03-05  Martin Sebor  <msebor@redhat.com>
 
        * PR testsuite/63175
index 20e390f13d5de0d4f6e82d0ffa67553956fdd348..5014f6f1f7efc58a5c43dbaa7087aaba595e26ce 100644 (file)
@@ -6,6 +6,7 @@
 struct S { int a[10]; };
 struct T { int l; int a[]; };
 struct U { int l; int a[0]; };
+struct V { int l; int a[1]; };
 
 __attribute__ ((noinline, noclone))
 void
@@ -64,9 +65,14 @@ main (void)
   struct T *t = (struct T *) __builtin_malloc (sizeof (struct T) + 10);
   t->a[1] = 1;
 
+  /* Don't instrument zero-sized arrays (GNU extension).  */
   struct U *u = (struct U *) __builtin_malloc (sizeof (struct U) + 10);
   u->a[1] = 1;
 
+  /* Don't instrument last array in a struct.  */
+  struct V *v = (struct V *) __builtin_malloc (sizeof (struct V) + 10);
+  v->a[1] = 1;
+
   long int *d[10][5];
   d[9][0] = (long int *) 0;
   d[8][3] = d[9][0];
diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-8.c b/gcc/testsuite/c-c++-common/ubsan/bounds-8.c
new file mode 100644 (file)
index 0000000..9a1b1d2
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR sanitizer/65280 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+int
+main (void)
+{
+  int *t = (int *) __builtin_malloc (sizeof (int) * 10);
+  int (*a)[1] = (int (*)[1]) t;
+  (*a)[2] = 1;
+}
+
+/* { dg-output "index 2 out of bounds for type 'int \\\[1\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-9.c b/gcc/testsuite/c-c++-common/ubsan/bounds-9.c
new file mode 100644 (file)
index 0000000..61c11f4
--- /dev/null
@@ -0,0 +1,24 @@
+/* PR sanitizer/65280 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+/* Origin: Martin Uecker <uecker@eecs.berkeley.edu> */
+
+void
+foo (volatile int (*a)[3])
+{
+  (*a)[3] = 1; // error
+  a[0][0] = 1; // ok
+  a[1][0] = 1; // ok
+  a[1][4] = 1; // error
+}
+
+int
+main ()
+{
+  volatile int a[20];
+  foo ((int (*)[3]) &a);
+  return 0;
+}
+
+/* { dg-output "index 3 out of bounds for type 'int \\\[3\\\]'\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*index 4 out of bounds for type 'int \\\[3\\\]'" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/bounds-2.c b/gcc/testsuite/gcc.dg/ubsan/bounds-2.c
new file mode 100644 (file)
index 0000000..3e88035
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR sanitizer/65280 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+void
+foo (int n, int (*b)[n])
+{
+  (*b)[n] = 1;
+}
+
+int
+main ()
+{
+  int a[20];
+  foo (3, (int (*)[3]) &a);
+}
+
+/* { dg-output "index 3 out of bounds for type 'int \\\[\\\*\\\]'\[^\n\r]*(\n|\r\n|\r)" } */