aboutsummaryrefslogtreecommitdiff
path: root/gcc/toplev.cc
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2023-08-01 17:30:13 -0400
committerMarek Polacek <polacek@redhat.com>2023-11-23 11:54:17 -0500
commit24592abd68e6efd4ab00c23d4702a046e63f24aa (patch)
tree6c8cf9935b66dbd28ad3f5891037b0f7da8c5433 /gcc/toplev.cc
parent2eb833534c7e715c276658ecb810715e8718e5c3 (diff)
downloadgcc-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.cc25
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)