diff options
author | Jakub Jelinek <jakub@redhat.com> | 2022-06-18 11:09:48 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2022-06-18 11:09:48 +0200 |
commit | 2c7cfc7b418564a2f1f0e7a5b38dec7013ba5e18 (patch) | |
tree | b9fab7e419fe1d603782f3010a4b3cee040c9e37 /gcc/doc | |
parent | ef662120177d39af5f88ffc622d90bb6ae0ca1d3 (diff) | |
download | gcc-2c7cfc7b418564a2f1f0e7a5b38dec7013ba5e18.zip gcc-2c7cfc7b418564a2f1f0e7a5b38dec7013ba5e18.tar.gz gcc-2c7cfc7b418564a2f1f0e7a5b38dec7013ba5e18.tar.bz2 |
ubsan: Add -fsanitize-trap= support
On Thu, Jun 16, 2022 at 09:32:02PM +0100, Jonathan Wakely wrote:
> It looks like clang has addressed this deficiency now:
>
> https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#usage
Thanks, that is roughly what I'd implement anyway and apparently they have
it already since 2015, we've added the -fsanitize-undefined-trap-on-error
support back in 2014 and didn't change it since then.
As a small divergence from clang, I chose -fsanitize-undefined-trap-on-error
to be a (deprecated) alias for -fsanitize-trap aka -fsanitize-trap=all
rather thn -fsanitize-trap=undefined which seems to be what clang does,
because for a deprecated option it is IMHO more important backwards
compatibility with what gcc did over the past 8 years rather than clang
compatibility.
Some sanitizers (e.g. asan, lsan, tsan) don't support traps,
-fsanitize-trap=address etc. will be rejected (if enabled at the end of
command line), -fno-sanitize-trap= can be specified even for them.
This is similar behavior to -fsanitize-recover=.
One complication is vptr sanitization, which can't easily trap,
as the whole slow path of the checking is inside of libubsan.
Previously, -fsanitize=vptr -fsanitize-undefined-trap-on-error
silently ignored vptr sanitization.
This patch similarly to what clang does will accept
-fsanitize-trap=all or -fsanitize-trap=undefined which enable
the vptr bit as trapping and again that causes silent disabling
of vptr sanitization, while -fsanitize-trap=vptr is rejected
(already during option processing).
2022-06-18 Jakub Jelinek <jakub@redhat.com>
gcc/
* common.opt (flag_sanitize_trap): New variable.
(fsanitize-trap=, fsanitize-trap): New options.
(fsanitize-undefined-trap-on-error): Change into deprecated alias
for -fsanitize-trap=all.
* opts.h (struct sanitizer_opts_s): Add can_trap member.
* opts.cc (finish_options): Complain about unsupported
-fsanitize-trap= options.
(sanitizer_opts): Add can_trap values to all entries.
(get_closest_sanitizer_option): Ignore -fsanitize-trap=
options which have can_trap false.
(parse_sanitizer_options): Add support for -fsanitize-trap=.
For -fsanitize-trap=all, enable
SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT. Disallow
-fsanitize-trap=vptr here.
(common_handle_option): Handle OPT_fsanitize_trap_ and
OPT_fsanitize_trap.
* sanopt.cc (maybe_optimize_ubsan_null_ifn): Check
flag_sanitize_trap & SANITIZE_{NULL,ALIGNMENT} instead of
flag_sanitize_undefined_trap_on_error.
* gcc.cc (sanitize_spec_function): Use
flag_sanitize & ~flag_sanitize_trap instead of flag_sanitize
and drop use of flag_sanitize_undefined_trap_on_error in
"undefined" handling.
* ubsan.cc (ubsan_instrument_unreachable): Use
flag_sanitize_trap & SANITIZE_??? instead of
flag_sanitize_undefined_trap_on_error.
(ubsan_expand_bounds_ifn, ubsan_expand_null_ifn,
ubsan_expand_objsize_ifn, ubsan_expand_ptr_ifn,
ubsan_build_overflow_builtin, instrument_bool_enum_load,
ubsan_instrument_float_cast, instrument_nonnull_arg,
instrument_nonnull_return, instrument_builtin): Likewise.
* doc/invoke.texi (-fsanitize-trap=, -fsanitize-trap): Document.
(-fsanitize-undefined-trap-on-error): Document as deprecated
alias of -fsanitize-trap.
gcc/c-family/
* c-ubsan.cc (ubsan_instrument_division, ubsan_instrument_shift):
Use flag_sanitize_trap & SANITIZE_??? instead of
flag_sanitize_undefined_trap_on_error. If 2 sanitizers are involved
and flag_sanitize_trap differs for them, emit __builtin_trap only
for the comparison where trap is requested.
(ubsan_instrument_vla, ubsan_instrument_return): Use
lag_sanitize_trap & SANITIZE_??? instead of
flag_sanitize_undefined_trap_on_error.
gcc/cp/
* cp-ubsan.cc (cp_ubsan_instrument_vptr_p): Use
flag_sanitize_trap & SANITIZE_VPTR instead of
flag_sanitize_undefined_trap_on_error.
gcc/testsuite/
* c-c++-common/ubsan/nonnull-4.c: Use -fsanitize-trap=all
instead of -fsanitize-undefined-trap-on-error.
* c-c++-common/ubsan/div-by-zero-4.c: Use
-fsanitize-trap=signed-integer-overflow instead of
-fsanitize-undefined-trap-on-error.
* c-c++-common/ubsan/overflow-add-4.c: Use -fsanitize-trap=undefined
instead of -fsanitize-undefined-trap-on-error.
* c-c++-common/ubsan/pr56956.c: Likewise.
* c-c++-common/ubsan/pr68142.c: Likewise.
* c-c++-common/ubsan/pr80932.c: Use
-fno-sanitize-trap=all -fsanitize-trap=shift,undefined
instead of -fsanitize-undefined-trap-on-error.
* c-c++-common/ubsan/align-8.c: Use -fsanitize-trap=alignment
instead of -fsanitize-undefined-trap-on-error.
Diffstat (limited to 'gcc/doc')
-rw-r--r-- | gcc/doc/invoke.texi | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 60b7b5a..50f5787 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -609,6 +609,7 @@ Objective-C and Objective-C++ Dialects}. -fprofile-exclude-files=@var{regex} @gol -fprofile-reproducible=@r{[}multithreaded@r{|}parallel-runs@r{|}serial@r{]} @gol -fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol +-fsanitize-trap -fsanitize-trap=@var{style} @gol -fasan-shadow-offset=@var{number} -fsanitize-sections=@var{s1},@var{s2},... @gol -fsanitize-undefined-trap-on-error -fbounds-check @gol -fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]} @gol @@ -16116,13 +16117,37 @@ undefined,float-cast-overflow,float-divide-by-zero,bounds-strict Enable sanitization of local variables to detect use-after-scope bugs. The option sets @option{-fstack-reuse} to @samp{none}. +@item -fsanitize-trap@r{[}=@var{opts}@r{]} +@opindex fsanitize-trap +@opindex fno-sanitize-trap +The @option{-fsanitize-trap=} option instructs the compiler to +report for sanitizers mentioned in comma-separated list of @var{opts} +undefined behavior using @code{__builtin_trap} rather than a @code{libubsan} +library routine. If this option is enabled for certain sanitizer, +it takes precedence over the @option{-fsanitizer-recover=} for that +sanitizer, @code{__builtin_trap} will be emitted and be fatal regardless +of whether recovery is enabled or disabled using @option{-fsanitize-recover=}. + +The advantage of this is that the @code{libubsan} library is not needed +and is not linked in, so this is usable even in freestanding environments. + +Currently this feature works with @option{-fsanitize=undefined} (and its suboptions +except for @option{-fsanitize=vptr}), @option{-fsanitize=float-cast-overflow}, +@option{-fsanitize=float-divide-by-zero} and +@option{-fsanitize=bounds-strict}. @code{-fsanitize-trap=all} can be also +specified, which enables it for @code{undefined} suboptions, +@option{-fsanitize=float-cast-overflow}, +@option{-fsanitize=float-divide-by-zero} and +@option{-fsanitize=bounds-strict}. +If @code{-fsanitize-trap=undefined} or @code{-fsanitize-trap=all} is used +and @code{-fsanitize=vptr} is enabled on the command line, the +instrumentation is silently ignored as the instrumentation always needs +@code{libubsan} support, @option{-fsanitize-trap=vptr} is not allowed. + @item -fsanitize-undefined-trap-on-error @opindex fsanitize-undefined-trap-on-error -The @option{-fsanitize-undefined-trap-on-error} option instructs the compiler to -report undefined behavior using @code{__builtin_trap} rather than -a @code{libubsan} library routine. The advantage of this is that the -@code{libubsan} library is not needed and is not linked in, so this -is usable even in freestanding environments. +The @option{-fsanitize-undefined-trap-on-error} option is deprecated +equivalent of @option{-fsanitize-trap=all}. @item -fsanitize-coverage=trace-pc @opindex fsanitize-coverage=trace-pc |