From: Marek Polacek Date: Fri, 6 Mar 2015 23:44:56 +0000 (+0000) Subject: re PR sanitizer/65280 (-fsanitize=bounds does not detect out-of-bounds access) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04fd785e38c4c37ae4f71704397a27a924baf4d9;p=gcc.git re PR sanitizer/65280 (-fsanitize=bounds does not detect out-of-bounds access) 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 From-SVN: r221250 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3b7801ed54a..f71958d8866 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-03-07 Marek Polacek + Martin Uecker + + PR sanitizer/65280 + * doc/invoke.texi: Update description of -fsanitize=bounds. + 2015-03-06 Wilco Dijkstra * tree-ssa-phiopt.c (neg_replacement): Remove. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index fa08958ac6c..6bd5a28fa8b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2015-03-07 Marek Polacek + + 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 Jonathan Wakely diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c index 90d59c03a16..a14426f9624 100644 --- a/gcc/c-family/c-ubsan.c +++ b/gcc/c-family/c-ubsan.c @@ -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; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 006a852af19..67814d40d5f 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 702e06bad09..0a9c561c1ae 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2015-03-07 Marek Polacek + Martin Uecker + + 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 * PR testsuite/63175 diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-1.c b/gcc/testsuite/c-c++-common/ubsan/bounds-1.c index 20e390f13d5..5014f6f1f7e 100644 --- a/gcc/testsuite/c-c++-common/ubsan/bounds-1.c +++ b/gcc/testsuite/c-c++-common/ubsan/bounds-1.c @@ -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 index 00000000000..9a1b1d25c67 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/bounds-8.c @@ -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 index 00000000000..61c11f4b3b8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/bounds-9.c @@ -0,0 +1,24 @@ +/* PR sanitizer/65280 */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=bounds" } */ +/* Origin: Martin Uecker */ + +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 index 00000000000..3e88035b206 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/bounds-2.c @@ -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)" } */