diff options
author | Marek Polacek <polacek@redhat.com> | 2023-08-01 17:30:13 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2023-11-23 11:54:17 -0500 |
commit | 24592abd68e6efd4ab00c23d4702a046e63f24aa (patch) | |
tree | 6c8cf9935b66dbd28ad3f5891037b0f7da8c5433 /gcc/toplev.cc | |
parent | 2eb833534c7e715c276658ecb810715e8718e5c3 (diff) | |
download | gcc-24592abd68e6efd4ab00c23d4702a046e63f24aa.zip gcc-24592abd68e6efd4ab00c23d4702a046e63f24aa.tar.gz gcc-24592abd68e6efd4ab00c23d4702a046e63f24aa.tar.bz2 |
gcc: Introduce -fhardened
In <https://gcc.gnu.org/pipermail/gcc-patches/2023-August/628748.html>
I proposed -fhardened, a new umbrella option that enables a reasonable set
of hardening flags. The read of the room seems to be that the option
would be useful. So here's a patch implementing that option.
Currently, -fhardened enables:
-D_FORTIFY_SOURCE=3 (or =2 for older glibcs)
-D_GLIBCXX_ASSERTIONS
-ftrivial-auto-var-init=zero
-fPIE -pie -Wl,-z,relro,-z,now
-fstack-protector-strong
-fstack-clash-protection
-fcf-protection=full (x86 GNU/Linux only)
-fhardened will not override options that were specified on the command line
(before or after -fhardened). For example,
-D_FORTIFY_SOURCE=1 -fhardened
means that _FORTIFY_SOURCE=1 will be used. Similarly,
-fhardened -fstack-protector
will not enable -fstack-protector-strong.
Currently, -fhardened is only supported on GNU/Linux.
In DW_AT_producer it is reflected only as -fhardened; it doesn't expand
to anything. This patch provides -Whardened, enabled by default, which
warns when -fhardened couldn't enable a particular option. I think most
often it will say that _FORTIFY_SOURCE wasn't enabled because optimization
were not enabled.
gcc/c-family/ChangeLog:
* c-opts.cc: Include "target.h".
(c_finish_options): Maybe cpp_define _FORTIFY_SOURCE
and _GLIBCXX_ASSERTIONS.
gcc/ChangeLog:
* common.opt (Whardened, fhardened): New options.
* config.in: Regenerate.
* config/bpf/bpf.cc: Include "opts.h".
(bpf_option_override): If flag_stack_protector_set_by_fhardened_p, do
not inform that -fstack-protector does not work.
* config/i386/i386-options.cc (ix86_option_override_internal): When
-fhardened, maybe enable -fcf-protection=full.
* config/linux-protos.h (linux_fortify_source_default_level): Declare.
* config/linux.cc (linux_fortify_source_default_level): New.
* config/linux.h (TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL): Redefine.
* configure: Regenerate.
* configure.ac: Check if the linker supports '-z now' and '-z relro'.
Check if -fhardened is supported on $target_os.
* doc/invoke.texi: Document -fhardened and -Whardened.
* doc/tm.texi: Regenerate.
* doc/tm.texi.in (TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL): Add.
* gcc.cc (driver_handle_option): Remember if any link options or -static
were specified on the command line.
(process_command): When -fhardened, maybe enable -pie and
-Wl,-z,relro,-z,now.
* opts.cc (flag_stack_protector_set_by_fhardened_p): New global.
(finish_options): When -fhardened, enable
-ftrivial-auto-var-init=zero and -fstack-protector-strong.
(print_help_hardened): New.
(print_help): Call it.
* opts.h (flag_stack_protector_set_by_fhardened_p): Declare.
* target.def (fortify_source_default_level): New target hook.
* targhooks.cc (default_fortify_source_default_level): New.
* targhooks.h (default_fortify_source_default_level): Declare.
* toplev.cc (process_options): When -fhardened, enable
-fstack-clash-protection. If flag_stack_protector_set_by_fhardened_p,
do not warn that -fstack-protector not supported for this target.
Don't enable -fhardened when !HAVE_FHARDENED_SUPPORT.
gcc/testsuite/ChangeLog:
* gcc.misc-tests/help.exp: Test -fhardened.
* c-c++-common/fhardened-1.S: New test.
* c-c++-common/fhardened-1.c: New test.
* c-c++-common/fhardened-10.c: New test.
* c-c++-common/fhardened-11.c: New test.
* c-c++-common/fhardened-12.c: New test.
* c-c++-common/fhardened-13.c: New test.
* c-c++-common/fhardened-14.c: New test.
* c-c++-common/fhardened-15.c: New test.
* c-c++-common/fhardened-2.c: New test.
* c-c++-common/fhardened-3.c: New test.
* c-c++-common/fhardened-4.c: New test.
* c-c++-common/fhardened-5.c: New test.
* c-c++-common/fhardened-6.c: New test.
* c-c++-common/fhardened-7.c: New test.
* c-c++-common/fhardened-8.c: New test.
* c-c++-common/fhardened-9.c: New test.
* gcc.target/i386/cf_check-6.c: New test.
Diffstat (limited to 'gcc/toplev.cc')
-rw-r--r-- | gcc/toplev.cc | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 8c3fcd3..85450d9 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -1568,6 +1568,13 @@ process_options () flag_associative_math = 0; } + if (flag_hardened && !HAVE_FHARDENED_SUPPORT) + { + warning_at (UNKNOWN_LOCATION, 0, + "%<-fhardened%> not supported for this target"); + flag_hardened = 0; + } + /* -fstack-clash-protection is not currently supported on targets where the stack grows up. */ if (flag_stack_clash_protection && !STACK_GROWS_DOWNWARD) @@ -1577,6 +1584,19 @@ process_options () "where the stack grows from lower to higher addresses"); flag_stack_clash_protection = 0; } + else if (flag_hardened) + { + if (!flag_stack_clash_protection + /* Don't enable -fstack-clash-protection when -fstack-check= + is used: it would result in confusing errors. */ + && flag_stack_check == NO_STACK_CHECK) + flag_stack_clash_protection = 1; + else if (flag_stack_check != NO_STACK_CHECK) + warning_at (UNKNOWN_LOCATION, OPT_Whardened, + "%<-fstack-clash-protection%> is not enabled by " + "%<-fhardened%> because %<-fstack-check%> was " + "specified on the command line"); + } /* We cannot support -fstack-check= and -fstack-clash-protection at the same time. */ @@ -1592,8 +1612,9 @@ process_options () target already uses a soft frame pointer, the transition is trivial. */ if (!FRAME_GROWS_DOWNWARD && flag_stack_protect) { - warning_at (UNKNOWN_LOCATION, 0, - "%<-fstack-protector%> not supported for this target"); + if (!flag_stack_protector_set_by_fhardened_p) + warning_at (UNKNOWN_LOCATION, 0, + "%<-fstack-protector%> not supported for this target"); flag_stack_protect = 0; } if (!flag_stack_protect) |