From 0dda258b6f3194849dc9a47aa9417d7ce942a3ec Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 13 Jun 2016 23:01:44 +0200 Subject: [PATCH] re PR sanitizer/71498 (ubsan bounds checking influenced by surrounding code) PR sanitizer/71498 * c-gimplify.c (ubsan_walk_array_refs_r): Set *walk_subtrees = 0 on all BIND_EXPRs, and on all BIND_EXPRs recurse also on BIND_EXPR_BODY. * c-c++-common/ubsan/bounds-13.c: New test. From-SVN: r237409 --- gcc/c-family/ChangeLog | 4 +++ gcc/c-family/c-gimplify.c | 12 ++++---- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/c-c++-common/ubsan/bounds-13.c | 31 ++++++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/ubsan/bounds-13.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 69ba05ca49f..a3e1fd8958b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,5 +1,9 @@ 2016-06-13 Jakub Jelinek + PR sanitizer/71498 + * c-gimplify.c (ubsan_walk_array_refs_r): Set *walk_subtrees = 0 on + all BIND_EXPRs, and on all BIND_EXPRs recurse also on BIND_EXPR_BODY. + PR preprocessor/71183 * c-ppoutput.c (init_pp_output): Set cb->get_source_date_epoch to cb_get_source_date_epoch. diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c index 0757193beea..c18b057727c 100644 --- a/gcc/c-family/c-gimplify.c +++ b/gcc/c-family/c-gimplify.c @@ -67,23 +67,23 @@ ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data) { hash_set *pset = (hash_set *) data; - /* Since walk_tree doesn't call the callback function on the decls - in BIND_EXPR_VARS, we have to walk them manually. */ if (TREE_CODE (*tp) == BIND_EXPR) { + /* Since walk_tree doesn't call the callback function on the decls + in BIND_EXPR_VARS, we have to walk them manually, so we can avoid + instrumenting DECL_INITIAL of TREE_STATIC vars. */ + *walk_subtrees = 0; for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl)) { if (TREE_STATIC (decl)) - { - *walk_subtrees = 0; - continue; - } + continue; walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, pset, pset); walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, pset, pset); walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, pset, pset); } + walk_tree (&BIND_EXPR_BODY (*tp), ubsan_walk_array_refs_r, pset, pset); } else if (TREE_CODE (*tp) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (*tp, 0)) == ARRAY_REF) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 33ff1268159..45862f3851c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-06-13 Jakub Jelinek + PR sanitizer/71498 + * c-c++-common/ubsan/bounds-13.c: New test. + PR preprocessor/71183 * gcc.dg/cpp/source_date_epoch-3.c: New test. diff --git a/gcc/testsuite/c-c++-common/ubsan/bounds-13.c b/gcc/testsuite/c-c++-common/ubsan/bounds-13.c new file mode 100644 index 00000000000..25b0467ec67 --- /dev/null +++ b/gcc/testsuite/c-c++-common/ubsan/bounds-13.c @@ -0,0 +1,31 @@ +/* PR sanitizer/71498 */ +/* { dg-do run } */ +/* { dg-options "-fsanitize=bounds -Wno-array-bounds" } */ + +struct S { int a[100]; int b, c; } s; + +__attribute__((noinline, noclone)) int +foo (int x) +{ + return s.a[x]; +} + +__attribute__((noinline, noclone)) int +bar (int x) +{ + static int *d = &s.a[99]; + asm volatile ("" : : "r" (&d)); + return s.a[x]; +} + +int +main () +{ + volatile int a = 0; + a += foo (100); + a += bar (100); + return 0; +} + +/* { dg-output "index 100 out of bounds for type 'int \\\[100\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*index 100 out of bounds for type 'int \\\[100\\\]'\[^\n\r]*(\n|\r\n|\r)" } */ -- 2.30.2