This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [ubsan] Add -fsanitize=bounds-strict
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>
- Cc: Martin Uecker <uecker at eecs dot berkeley dot edu>
- Date: Wed, 6 May 2015 23:14:08 +0200
- Subject: Re: [ubsan] Add -fsanitize=bounds-strict
- Authentication-results: sourceware.org; auth=none
- References: <20150429151310 dot GA3384 at redhat dot com>
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 <polacek@redhat.com>
> Martin Uecker <uecker@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