Ping. On Wed, Apr 29, 2015 at 05:13:11PM +0200, Marek Polacek wrote: > This patch adds the -fsanitize=bounds-strict option Martin U. wanted; it is > actually based on his earlier patch, I did only some small adjustments. > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2015-04-29 Marek Polacek <pola...@redhat.com> > Martin Uecker <uec...@eecs.berkeley.edu> > > * c-ubsan.c (ubsan_instrument_bounds): Don't skip instrumenting > flexible member array-like members if SANITIZE_BOUNDS_STRICT. > > * doc/invoke.texi: Document -fsanitize=bounds-strict. > * flag-types.h (enum sanitize_code): Add SANITIZE_BOUNDS_STRICT, or it > into SANITIZE_NONDEFAULT. > * opts.c (common_handle_option): Handle -fsanitize=bounds-strict. > > * c-c++-common/ubsan/bounds-10.c: New test. > > diff --git gcc/c-family/c-ubsan.c gcc/c-family/c-ubsan.c > index a14426f..dbbdc5b 100644 > --- gcc/c-family/c-ubsan.c > +++ gcc/c-family/c-ubsan.c > @@ -301,9 +301,11 @@ ubsan_instrument_bounds (location_t loc, tree array, > tree *index, > bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound, > build_int_cst (TREE_TYPE (bound), 1)); > > - /* Detect flexible array members and suchlike. */ > + /* Detect flexible array members and suchlike, unless > + -fsanitize=bounds-strict. */ > tree base = get_base_address (array); > - if (TREE_CODE (array) == COMPONENT_REF > + if ((flag_sanitize & SANITIZE_BOUNDS_STRICT) == 0 > + && TREE_CODE (array) == COMPONENT_REF > && base && (TREE_CODE (base) == INDIRECT_REF > || TREE_CODE (base) == MEM_REF)) > { > diff --git gcc/doc/invoke.texi gcc/doc/invoke.texi > index 7d2f6e5..d050ba6 100644 > --- gcc/doc/invoke.texi > +++ gcc/doc/invoke.texi > @@ -5728,6 +5728,13 @@ This option enables instrumentation of array bounds. > Various out of bounds > accesses are detected. Flexible array members, flexible array member-like > arrays, and initializers of variables with static storage are not > instrumented. > > +@item -fsanitize=bounds-strict > +@opindex fsanitize=bounds-strict > +This option enables strict instrumentation of array bounds. Most out of > bounds > +accesses are detected, including flexible array members and flexible array > +member-like arrays. Initializers of variables with static storage are not > +instrumented. > + > @item -fsanitize=alignment > @opindex fsanitize=alignment > > diff --git gcc/flag-types.h gcc/flag-types.h > index bfdce44..2f820a5 100644 > --- gcc/flag-types.h > +++ gcc/flag-types.h > @@ -238,6 +238,7 @@ enum sanitize_code { > SANITIZE_RETURNS_NONNULL_ATTRIBUTE = 1UL << 19, > SANITIZE_OBJECT_SIZE = 1UL << 20, > SANITIZE_VPTR = 1UL << 21, > + SANITIZE_BOUNDS_STRICT = 1UL << 22, > SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | > SANITIZE_UNREACHABLE > | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN > | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM > @@ -246,6 +247,7 @@ enum sanitize_code { > | SANITIZE_RETURNS_NONNULL_ATTRIBUTE > | SANITIZE_OBJECT_SIZE | SANITIZE_VPTR, > SANITIZE_NONDEFAULT = SANITIZE_FLOAT_DIVIDE | SANITIZE_FLOAT_CAST > + | SANITIZE_BOUNDS_STRICT > }; > > /* flag_vtable_verify initialization levels. */ > diff --git gcc/opts.c gcc/opts.c > index 39c190d..8c6716b 100644 > --- gcc/opts.c > +++ gcc/opts.c > @@ -1584,6 +1584,8 @@ common_handle_option (struct gcc_options *opts, > { "float-cast-overflow", SANITIZE_FLOAT_CAST, > sizeof "float-cast-overflow" - 1 }, > { "bounds", SANITIZE_BOUNDS, sizeof "bounds" - 1 }, > + { "bounds-strict", SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, > + sizeof "bounds-strict" - 1 }, > { "alignment", SANITIZE_ALIGNMENT, sizeof "alignment" - 1 }, > { "nonnull-attribute", SANITIZE_NONNULL_ATTRIBUTE, > sizeof "nonnull-attribute" - 1 }, > diff --git gcc/testsuite/c-c++-common/ubsan/bounds-10.c > gcc/testsuite/c-c++-common/ubsan/bounds-10.c > index e69de29..a6187b5 100644 > --- gcc/testsuite/c-c++-common/ubsan/bounds-10.c > +++ gcc/testsuite/c-c++-common/ubsan/bounds-10.c > @@ -0,0 +1,16 @@ > +/* { dg-do run } */ > +/* { dg-options "-fsanitize=bounds-strict" } */ > + > +struct V { int l; int a[1]; }; > + > +int > +main (void) > +{ > + /* For strict, do instrument last array in a struct. */ > + struct V *v = (struct V *) __builtin_malloc (sizeof (struct V) + 10); > + v->a[1] = 1; > + > + return 0; > +} > + > +/* { dg-output "index 1 out of bounds for type 'int \\\[1\\\]'" } */ > > Marek
Marek