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.
This commit is contained in:
parent
2eb833534c
commit
24592abd68
38 changed files with 588 additions and 14 deletions
|
@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "target.h"
|
||||
#include "c-target.h"
|
||||
#include "c-common.h"
|
||||
#include "memmodel.h"
|
||||
|
@ -1573,6 +1574,9 @@ c_finish_options (void)
|
|||
cb_file_change (parse_in, cmd_map);
|
||||
linemap_line_start (line_table, 0, 1);
|
||||
|
||||
bool fortify_seen_p = false;
|
||||
bool cxx_assert_seen_p = false;
|
||||
|
||||
/* All command line defines must have the same location. */
|
||||
cpp_force_token_locations (parse_in, line_table->highest_line);
|
||||
for (size_t i = 0; i < deferred_count; i++)
|
||||
|
@ -1590,6 +1594,41 @@ c_finish_options (void)
|
|||
else
|
||||
cpp_assert (parse_in, opt->arg);
|
||||
}
|
||||
|
||||
if (UNLIKELY (flag_hardened)
|
||||
&& (opt->code == OPT_D || opt->code == OPT_U))
|
||||
{
|
||||
if (!fortify_seen_p)
|
||||
fortify_seen_p
|
||||
= (!strncmp (opt->arg, "_FORTIFY_SOURCE", 15)
|
||||
&& (opt->arg[15] == '\0' || opt->arg[15] == '='));
|
||||
if (!cxx_assert_seen_p)
|
||||
cxx_assert_seen_p
|
||||
= (!strncmp (opt->arg, "_GLIBCXX_ASSERTIONS", 19)
|
||||
&& (opt->arg[19] == '\0' || opt->arg[19] == '='));
|
||||
}
|
||||
}
|
||||
|
||||
if (flag_hardened)
|
||||
{
|
||||
if (!fortify_seen_p && optimize > 0)
|
||||
cpp_define_formatted (parse_in, "_FORTIFY_SOURCE=%u",
|
||||
targetm.fortify_source_default_level ());
|
||||
else if (optimize == 0)
|
||||
warning_at (UNKNOWN_LOCATION, OPT_Whardened,
|
||||
"%<_FORTIFY_SOURCE%> is not enabled by %<-fhardened%> "
|
||||
"because optimizations are turned off");
|
||||
else
|
||||
warning_at (UNKNOWN_LOCATION, OPT_Whardened,
|
||||
"%<_FORTIFY_SOURCE%> is not enabled by %<-fhardened%> "
|
||||
"because it was specified in %<-D%> or %<-U%>");
|
||||
if (!cxx_assert_seen_p)
|
||||
cpp_define (parse_in, "_GLIBCXX_ASSERTIONS");
|
||||
else
|
||||
warning_at (UNKNOWN_LOCATION, OPT_Whardened,
|
||||
"%<_GLIBCXX_ASSERTIONS%> is not enabled by "
|
||||
"%<-fhardened%> because it was specified in %<-D%> "
|
||||
"or %<-U%>");
|
||||
}
|
||||
|
||||
cpp_stop_forcing_token_locations (parse_in);
|
||||
|
|
|
@ -634,6 +634,10 @@ Wfree-nonheap-object
|
|||
Common Var(warn_free_nonheap_object) Init(1) Warning
|
||||
Warn when attempting to free a non-heap object.
|
||||
|
||||
Whardened
|
||||
Common Var(warn_hardened) Init(1) Warning
|
||||
Warn when -fhardened did not enable an option from its set.
|
||||
|
||||
Whsa
|
||||
Common Ignore Warning
|
||||
Does nothing. Preserved for backward compatibility.
|
||||
|
@ -1823,6 +1827,10 @@ fguess-branch-probability
|
|||
Common Var(flag_guess_branch_prob) Optimization
|
||||
Enable guessing of branch probabilities.
|
||||
|
||||
fhardened
|
||||
Common Driver Var(flag_hardened)
|
||||
Enable various security-relevant flags.
|
||||
|
||||
fharden-compares
|
||||
Common Var(flag_harden_compares) Optimization
|
||||
Harden conditionals not used in branches, checking reversed conditions.
|
||||
|
|
|
@ -1332,6 +1332,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
/* Define 0/1 if -fhardened is supported */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_FHARDENED_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 if you have the `fileno_unlocked' function. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_FILENO_UNLOCKED
|
||||
|
@ -1740,6 +1746,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
/* Define 0/1 if your linker supports -z now */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_LD_NOW_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
/* Define if your PowerPC64 linker only needs function descriptor syms. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_LD_NO_DOT_SYMS
|
||||
|
@ -1783,6 +1795,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
/* Define 0/1 if your linker supports -z relro */
|
||||
#ifndef USED_FOR_TARGET
|
||||
#undef HAVE_LD_RELRO_SUPPORT
|
||||
#endif
|
||||
|
||||
|
||||
/* Define if your linker links a mix of read-only and read-write sections into
|
||||
a read-write section. */
|
||||
#ifndef USED_FOR_TARGET
|
||||
|
|
|
@ -70,6 +70,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "gimplify-me.h"
|
||||
|
||||
#include "core-builtins.h"
|
||||
#include "opts.h"
|
||||
|
||||
/* Per-function machine data. */
|
||||
struct GTY(()) machine_function
|
||||
|
@ -250,9 +251,10 @@ bpf_option_override (void)
|
|||
/* Disable -fstack-protector as it is not supported in BPF. */
|
||||
if (flag_stack_protect)
|
||||
{
|
||||
inform (input_location,
|
||||
"%<-fstack-protector%> does not work "
|
||||
"on this architecture");
|
||||
if (!flag_stack_protector_set_by_fhardened_p)
|
||||
inform (input_location,
|
||||
"%<-fstack-protector%> does not work "
|
||||
"on this architecture");
|
||||
flag_stack_protect = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -3190,10 +3190,25 @@ ix86_option_override_internal (bool main_args_p,
|
|||
= build_target_option_node (opts, opts_set);
|
||||
}
|
||||
|
||||
const bool cf_okay_p = (TARGET_64BIT || TARGET_CMOV);
|
||||
/* When -fhardened, enable -fcf-protection=full, but only when it's
|
||||
compatible with this target, and when it wasn't already specified
|
||||
on the command line. */
|
||||
if (opts->x_flag_hardened && cf_okay_p)
|
||||
{
|
||||
if (opts->x_flag_cf_protection == CF_NONE)
|
||||
opts->x_flag_cf_protection = CF_FULL;
|
||||
else if (opts->x_flag_cf_protection != CF_FULL)
|
||||
warning_at (UNKNOWN_LOCATION, OPT_Whardened,
|
||||
"%<-fcf-protection=full%> is not enabled by "
|
||||
"%<-fhardened%> because it was specified on the command "
|
||||
"line");
|
||||
}
|
||||
|
||||
if (opts->x_flag_cf_protection != CF_NONE)
|
||||
{
|
||||
if ((opts->x_flag_cf_protection & CF_BRANCH) == CF_BRANCH
|
||||
&& !TARGET_64BIT && !TARGET_CMOV)
|
||||
&& !cf_okay_p)
|
||||
error ("%<-fcf-protection%> is not compatible with this target");
|
||||
|
||||
opts->x_flag_cf_protection
|
||||
|
|
|
@ -22,3 +22,4 @@ extern bool linux_has_ifunc_p (void);
|
|||
extern bool linux_libc_has_function (enum function_class fn_class, tree);
|
||||
|
||||
extern unsigned linux_libm_function_max_error (unsigned, machine_mode, bool);
|
||||
extern unsigned linux_fortify_source_default_level ();
|
||||
|
|
|
@ -49,3 +49,12 @@ linux_libm_function_max_error (unsigned cfn, machine_mode mode,
|
|||
return glibc_linux_libm_function_max_error (cfn, mode, boundary_p);
|
||||
return default_libm_function_max_error (cfn, mode, boundary_p);
|
||||
}
|
||||
|
||||
unsigned
|
||||
linux_fortify_source_default_level ()
|
||||
{
|
||||
if (OPTION_GLIBC && TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 35)
|
||||
return 3;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
|
|
@ -216,3 +216,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
# define TARGET_LIBM_FUNCTION_MAX_ERROR linux_libm_function_max_error
|
||||
|
||||
#endif
|
||||
|
||||
#undef TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL
|
||||
#define TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL linux_fortify_source_default_level
|
||||
|
|
68
gcc/configure
vendored
68
gcc/configure
vendored
|
@ -34638,7 +34638,7 @@ if test x"$ld_is_gold" = xno; then
|
|||
ld_bndplt_support=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -a bndplt option
|
||||
# Check if linker supports -z bndplt option
|
||||
if $gcc_cv_ld --help 2>&1 | grep -- '-z bndplt' > /dev/null; then
|
||||
ld_bndplt_support=yes
|
||||
fi
|
||||
|
@ -34767,6 +34767,72 @@ $as_echo "#define ENABLE_S390_EXCESS_FLOAT_PRECISION 1" >>confdefs.h
|
|||
;;
|
||||
esac
|
||||
|
||||
# Check if the linker supports '-z now'
|
||||
ld_now_support=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z now option" >&5
|
||||
$as_echo_n "checking linker -z now option... " >&6; }
|
||||
if test x"$ld_is_gold" = xyes; then
|
||||
ld_now_support=yes
|
||||
elif test $in_tree_ld = yes ; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then
|
||||
ld_now_support=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -z now
|
||||
if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then
|
||||
ld_now_support=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LD_NOW_SUPPORT `if test x"$ld_now_support" = xyes; then echo 1; else echo 0; fi`
|
||||
_ACEOF
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_now_support" >&5
|
||||
$as_echo "$ld_now_support" >&6; }
|
||||
|
||||
# Check if the linker supports '-z relro'
|
||||
ld_relro_support=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking linker -z relro option" >&5
|
||||
$as_echo_n "checking linker -z relro option... " >&6; }
|
||||
if test x"$ld_is_gold" = xyes; then
|
||||
ld_relro_support=yes
|
||||
elif test $in_tree_ld = yes ; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then
|
||||
ld_relro_support=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -z relro
|
||||
if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then
|
||||
ld_relro_support=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LD_RELRO_SUPPORT `if test x"$ld_relro_support" = xyes; then echo 1; else echo 0; fi`
|
||||
_ACEOF
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_relro_support" >&5
|
||||
$as_echo "$ld_relro_support" >&6; }
|
||||
|
||||
case $target_os in
|
||||
linux* | gnu*)
|
||||
# -fhardened is only supported on GNU/Linux.
|
||||
fhardened_support=yes
|
||||
;;
|
||||
*)
|
||||
fhardened_support=no
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_FHARDENED_SUPPORT `if test x"$fhardened_support" = xyes; then echo 1; else echo 0; fi`
|
||||
_ACEOF
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $fhardened_support" >&5
|
||||
$as_echo "$fhardened_support" >&6; }
|
||||
|
||||
# Configure the subdirectories
|
||||
# AC_CONFIG_SUBDIRS($subdirs)
|
||||
|
||||
|
|
|
@ -7764,7 +7764,7 @@ if test x"$ld_is_gold" = xno; then
|
|||
ld_bndplt_support=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -a bndplt option
|
||||
# Check if linker supports -z bndplt option
|
||||
if $gcc_cv_ld --help 2>&1 | grep -- '-z bndplt' > /dev/null; then
|
||||
ld_bndplt_support=yes
|
||||
fi
|
||||
|
@ -7865,6 +7865,61 @@ standards-compatible mode on s390 targets.])
|
|||
;;
|
||||
esac
|
||||
|
||||
# Check if the linker supports '-z now'
|
||||
ld_now_support=no
|
||||
AC_MSG_CHECKING(linker -z now option)
|
||||
if test x"$ld_is_gold" = xyes; then
|
||||
ld_now_support=yes
|
||||
elif test $in_tree_ld = yes ; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 14 -o "$gcc_cv_gld_major_version" -gt 2; then
|
||||
ld_now_support=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -z now
|
||||
if $gcc_cv_ld --help 2>&1 | grep -- '-z now' > /dev/null; then
|
||||
ld_now_support=yes
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(HAVE_LD_NOW_SUPPORT,
|
||||
[`if test x"$ld_now_support" = xyes; then echo 1; else echo 0; fi`],
|
||||
[Define 0/1 if your linker supports -z now])
|
||||
AC_MSG_RESULT($ld_now_support)
|
||||
|
||||
# Check if the linker supports '-z relro'
|
||||
ld_relro_support=no
|
||||
AC_MSG_CHECKING(linker -z relro option)
|
||||
if test x"$ld_is_gold" = xyes; then
|
||||
ld_relro_support=yes
|
||||
elif test $in_tree_ld = yes ; then
|
||||
if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 15 -o "$gcc_cv_gld_major_version" -gt 2; then
|
||||
ld_relro_support=yes
|
||||
fi
|
||||
elif test x$gcc_cv_ld != x; then
|
||||
# Check if linker supports -z relro
|
||||
if $gcc_cv_ld --help 2>&1 | grep -- '-z relro' > /dev/null; then
|
||||
ld_relro_support=yes
|
||||
fi
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(HAVE_LD_RELRO_SUPPORT,
|
||||
[`if test x"$ld_relro_support" = xyes; then echo 1; else echo 0; fi`],
|
||||
[Define 0/1 if your linker supports -z relro])
|
||||
AC_MSG_RESULT($ld_relro_support)
|
||||
|
||||
case $target_os in
|
||||
linux* | gnu*)
|
||||
# -fhardened is only supported on GNU/Linux.
|
||||
fhardened_support=yes
|
||||
;;
|
||||
*)
|
||||
fhardened_support=no
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_DEFINE_UNQUOTED(HAVE_FHARDENED_SUPPORT,
|
||||
[`if test x"$fhardened_support" = xyes; then echo 1; else echo 0; fi`],
|
||||
[Define 0/1 if -fhardened is supported])
|
||||
AC_MSG_RESULT($fhardened_support)
|
||||
|
||||
# Configure the subdirectories
|
||||
# AC_CONFIG_SUBDIRS($subdirs)
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-Wformat-y2k -Wframe-address
|
||||
-Wframe-larger-than=@var{byte-size} -Wno-free-nonheap-object
|
||||
-Wno-if-not-aligned -Wno-ignored-attributes
|
||||
-Wignored-qualifiers -Wno-incompatible-pointer-types
|
||||
-Wignored-qualifiers -Wno-incompatible-pointer-types -Whardened
|
||||
-Wimplicit -Wimplicit-fallthrough -Wimplicit-fallthrough=@var{n}
|
||||
-Wno-implicit-function-declaration -Wno-implicit-int
|
||||
-Winfinite-recursion
|
||||
|
@ -644,7 +644,7 @@ Objective-C and Objective-C++ Dialects}.
|
|||
-fasan-shadow-offset=@var{number} -fsanitize-sections=@var{s1},@var{s2},...
|
||||
-fsanitize-undefined-trap-on-error -fbounds-check
|
||||
-fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]}
|
||||
-fharden-compares -fharden-conditional-branches
|
||||
-fharden-compares -fharden-conditional-branches -fhardened
|
||||
-fharden-control-flow-redundancy -fhardcfr-skip-leaf
|
||||
-fhardcfr-check-exceptions -fhardcfr-check-returning-calls
|
||||
-fhardcfr-check-noreturn-calls=@r{[}always@r{|}no-xthrow@r{|}nothrow@r{|}never@r{]}
|
||||
|
@ -6873,6 +6873,18 @@ This warning is upgraded to an error by @option{-pedantic-errors}.
|
|||
Same as @option{-Wimplicit-int} and @option{-Wimplicit-function-declaration}.
|
||||
This warning is enabled by @option{-Wall}.
|
||||
|
||||
@opindex Whardened
|
||||
@opindex Wno-hardened
|
||||
@item -Whardened
|
||||
Warn when @option{-fhardened} did not enable an option from its set (for
|
||||
which see @option{-fhardened}). For instance, using @option{-fhardened}
|
||||
and @option{-fstack-protector} at the same time on the command line causes
|
||||
@option{-Whardened} to warn because @option{-fstack-protector-strong} is
|
||||
not enabled by @option{-fhardened}.
|
||||
|
||||
This warning is enabled by default and has effect only when @option{-fhardened}
|
||||
is enabled.
|
||||
|
||||
@opindex Wimplicit-fallthrough
|
||||
@opindex Wno-implicit-fallthrough
|
||||
@item -Wimplicit-fallthrough
|
||||
|
@ -17638,6 +17650,39 @@ made @option{no-xthrow} the default setting for this option: it excludes
|
|||
from the @code{noreturn} treatment only internal functions used to
|
||||
(re)raise exceptions, that are not affected by these optimizations.
|
||||
|
||||
@opindex fhardened
|
||||
@item -fhardened
|
||||
Enable a set of flags for C and C++ that improve the security of the
|
||||
generated code without affecting its ABI. The precise flags enabled
|
||||
may change between major releases of GCC, but are currently:
|
||||
|
||||
@c Keep this in sync with print_help_hardened!
|
||||
@gccoptlist{
|
||||
-D_FORTIFY_SOURCE=3
|
||||
-D_GLIBCXX_ASSERTIONS
|
||||
-ftrivial-auto-var-init=zero
|
||||
-fPIE -pie -Wl,-z,relro,-z,now
|
||||
-fstack-protector-strong
|
||||
-fstack-clash-protection
|
||||
-fcf-protection=full @r{(x86 GNU/Linux only)}
|
||||
}
|
||||
|
||||
The list of options enabled by @option{-fhardened} can be generated using
|
||||
the @option{--help=hardened} option.
|
||||
|
||||
When the system glibc is older than 2.35, @option{-D_FORTIFY_SOURCE=2}
|
||||
is used instead.
|
||||
|
||||
This option is intended to be used in production builds, not merely
|
||||
in debug builds.
|
||||
|
||||
Currently, @option{-fhardened} is only supported on GNU/Linux targets.
|
||||
|
||||
@option{-fhardened} only enables a particular option if it wasn't
|
||||
already specified anywhere on the command line. For instance,
|
||||
@option{-fhardened} @option{-fstack-protector} will only enable
|
||||
@option{-fstack-protector}, but not @option{-fstack-protector-strong}.
|
||||
|
||||
@opindex fstack-protector
|
||||
@item -fstack-protector
|
||||
Emit extra code to check for buffer overflows, such as stack smashing
|
||||
|
|
|
@ -5823,6 +5823,11 @@ This hook determines whether a function from a class of functions
|
|||
@code{(enum function_class)}@var{fcode} has a fast implementation.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} unsigned TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL (void)
|
||||
This hook determines what value _FORTIFY_SOURCE will be set to when using
|
||||
the command-line option -fhardened.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} unsigned TARGET_LIBM_FUNCTION_MAX_ERROR (unsigned @var{cfn}, machine_mode @var{mode}, bool @var{boundary_p})
|
||||
This hook determines expected maximum errors for math functions measured
|
||||
in ulps (units of the last place). 0 means 0.5ulps precision (correctly
|
||||
|
|
|
@ -4044,6 +4044,8 @@ macro, a reasonable default is used.
|
|||
|
||||
@hook TARGET_LIBC_HAS_FAST_FUNCTION
|
||||
|
||||
@hook TARGET_FORTIFY_SOURCE_DEFAULT_LEVEL
|
||||
|
||||
@hook TARGET_LIBM_FUNCTION_MAX_ERROR
|
||||
|
||||
@defmac NEXT_OBJC_RUNTIME
|
||||
|
|
48
gcc/gcc.cc
48
gcc/gcc.cc
|
@ -302,6 +302,13 @@ static size_t dumpdir_length = 0;
|
|||
driver added to dumpdir after dumpbase or linker output name. */
|
||||
static bool dumpdir_trailing_dash_added = false;
|
||||
|
||||
/* True if -r, -shared, -pie, or -no-pie were specified on the command
|
||||
line. */
|
||||
static bool any_link_options_p;
|
||||
|
||||
/* True if -static was specified on the command line. */
|
||||
static bool static_p;
|
||||
|
||||
/* Basename of dump and aux outputs, computed from dumpbase (given or
|
||||
derived from output name), to override input_basename in non-%w %b
|
||||
et al. */
|
||||
|
@ -4605,10 +4612,20 @@ driver_handle_option (struct gcc_options *opts,
|
|||
save_switch ("-o", 1, &arg, validated, true);
|
||||
return true;
|
||||
|
||||
#ifdef ENABLE_DEFAULT_PIE
|
||||
case OPT_pie:
|
||||
#ifdef ENABLE_DEFAULT_PIE
|
||||
/* -pie is turned on by default. */
|
||||
validated = true;
|
||||
#endif
|
||||
case OPT_r:
|
||||
case OPT_shared:
|
||||
case OPT_no_pie:
|
||||
any_link_options_p = true;
|
||||
break;
|
||||
|
||||
case OPT_static:
|
||||
static_p = true;
|
||||
break;
|
||||
|
||||
case OPT_static_libgcc:
|
||||
case OPT_shared_libgcc:
|
||||
|
@ -4984,6 +5001,35 @@ process_command (unsigned int decoded_options_count,
|
|||
#endif
|
||||
}
|
||||
|
||||
/* TODO: check if -static -pie works and maybe use it. */
|
||||
if (flag_hardened)
|
||||
{
|
||||
if (!any_link_options_p && !static_p)
|
||||
{
|
||||
#ifdef HAVE_LD_PIE
|
||||
save_switch (LD_PIE_SPEC, 0, NULL, /*validated=*/true, /*known=*/false);
|
||||
#endif
|
||||
/* These are passed straight down to collect2 so we have to break
|
||||
it up like this. */
|
||||
if (HAVE_LD_NOW_SUPPORT)
|
||||
{
|
||||
add_infile ("-z", "*");
|
||||
add_infile ("now", "*");
|
||||
}
|
||||
if (HAVE_LD_RELRO_SUPPORT)
|
||||
{
|
||||
add_infile ("-z", "*");
|
||||
add_infile ("relro", "*");
|
||||
}
|
||||
}
|
||||
/* We can't use OPT_Whardened yet. Sigh. */
|
||||
else if (warn_hardened)
|
||||
warning_at (UNKNOWN_LOCATION, 0,
|
||||
"linker hardening options not enabled by %<-fhardened%> "
|
||||
"because other link options were specified on the command "
|
||||
"line");
|
||||
}
|
||||
|
||||
/* Handle -gtoggle as it would later in toplev.cc:process_options to
|
||||
make the debug-level-gt spec function work as expected. */
|
||||
if (flag_gtoggle)
|
||||
|
|
68
gcc/opts.cc
68
gcc/opts.cc
|
@ -42,6 +42,10 @@ along with GCC; see the file COPYING3. If not see
|
|||
/* Set by -fcanon-prefix-map. */
|
||||
bool flag_canon_prefix_map;
|
||||
|
||||
/* Set by finish_options when flag_stack_protector was set only because of
|
||||
-fhardened. Yuck. */
|
||||
bool flag_stack_protector_set_by_fhardened_p;
|
||||
|
||||
static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
|
||||
|
||||
/* Names of fundamental debug info formats indexed by enum
|
||||
|
@ -1092,6 +1096,17 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
|
|||
opts->x_flag_section_anchors = 0;
|
||||
}
|
||||
|
||||
if (opts->x_flag_hardened)
|
||||
{
|
||||
if (!opts_set->x_flag_auto_var_init)
|
||||
opts->x_flag_auto_var_init = AUTO_INIT_ZERO;
|
||||
else if (opts->x_flag_auto_var_init != AUTO_INIT_ZERO)
|
||||
warning_at (loc, OPT_Whardened,
|
||||
"%<-ftrivial-auto-var-init=zero%> is not enabled by "
|
||||
"%<-fhardened%> because it was specified on the command "
|
||||
"line");
|
||||
}
|
||||
|
||||
if (!opts->x_flag_opts_finished)
|
||||
{
|
||||
/* We initialize opts->x_flag_pie to -1 so that targets can set a
|
||||
|
@ -1101,7 +1116,8 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
|
|||
/* We initialize opts->x_flag_pic to -1 so that we can tell if
|
||||
-fpic, -fPIC, -fno-pic or -fno-PIC is used. */
|
||||
if (opts->x_flag_pic == -1)
|
||||
opts->x_flag_pie = DEFAULT_FLAG_PIE;
|
||||
opts->x_flag_pie = (opts->x_flag_hardened
|
||||
? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE);
|
||||
else
|
||||
opts->x_flag_pie = 0;
|
||||
}
|
||||
|
@ -1116,9 +1132,29 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
|
|||
}
|
||||
|
||||
/* We initialize opts->x_flag_stack_protect to -1 so that targets
|
||||
can set a default value. */
|
||||
can set a default value. With --enable-default-ssp or -fhardened
|
||||
the default is -fstack-protector-strong. */
|
||||
if (opts->x_flag_stack_protect == -1)
|
||||
opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
|
||||
{
|
||||
/* This should check FRAME_GROWS_DOWNWARD, but on some targets it's
|
||||
defined in such a way that it uses flag_stack_protect which can't
|
||||
be used here. Moreover, some targets like BPF don't support
|
||||
-fstack-protector at all but we don't know that here. So remember
|
||||
that flag_stack_protect was set at the behest of -fhardened. */
|
||||
if (opts->x_flag_hardened)
|
||||
{
|
||||
opts->x_flag_stack_protect = SPCT_FLAG_STRONG;
|
||||
flag_stack_protector_set_by_fhardened_p = true;
|
||||
}
|
||||
else
|
||||
opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
|
||||
}
|
||||
else if (opts->x_flag_hardened
|
||||
&& opts->x_flag_stack_protect != SPCT_FLAG_STRONG)
|
||||
warning_at (UNKNOWN_LOCATION, OPT_Whardened,
|
||||
"%<-fstack-protector-strong%> is not enabled by "
|
||||
"%<-fhardened%> because it was specified on the command "
|
||||
"line");
|
||||
|
||||
if (opts->x_optimize == 0)
|
||||
{
|
||||
|
@ -2460,6 +2496,30 @@ parse_and_check_patch_area (const char *arg, bool report_error,
|
|||
free (patch_area_arg);
|
||||
}
|
||||
|
||||
/* Print options enabled by -fhardened. Keep this in sync with the manual! */
|
||||
|
||||
static void
|
||||
print_help_hardened ()
|
||||
{
|
||||
printf ("%s\n", "The following options are enabled by -fhardened:");
|
||||
/* Unfortunately, I can't seem to use targetm.fortify_source_default_level
|
||||
here. */
|
||||
printf (" %s\n", "-D_FORTIFY_SOURCE=3 (or =2 for glibc < 2.35)");
|
||||
printf (" %s\n", "-D_GLIBCXX_ASSERTIONS");
|
||||
printf (" %s\n", "-ftrivial-auto-var-init=zero");
|
||||
#ifdef HAVE_LD_PIE
|
||||
printf (" %s %s\n", "-fPIE", "-pie");
|
||||
#endif
|
||||
if (HAVE_LD_NOW_SUPPORT)
|
||||
printf (" %s\n", "-Wl,-z,now");
|
||||
if (HAVE_LD_RELRO_SUPPORT)
|
||||
printf (" %s\n", "-Wl,-z,relro");
|
||||
printf (" %s\n", "-fstack-protector-strong");
|
||||
printf (" %s\n", "-fstack-clash-protection");
|
||||
printf (" %s\n", "-fcf-protection=full");
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
/* Print help when OPT__help_ is set. */
|
||||
|
||||
void
|
||||
|
@ -2575,6 +2635,8 @@ print_help (struct gcc_options *opts, unsigned int lang_mask,
|
|||
}
|
||||
else if (lang_flag != 0)
|
||||
*pflags |= lang_flag;
|
||||
else if (strncasecmp (a, "hardened", len) == 0)
|
||||
print_help_hardened ();
|
||||
else
|
||||
warning (0,
|
||||
"unrecognized argument to %<--help=%> option: %q.*s",
|
||||
|
|
|
@ -344,6 +344,7 @@ struct cl_option_handlers
|
|||
/* Hold command-line options associated with stack limitation. */
|
||||
extern const char *opt_fstack_limit_symbol_arg;
|
||||
extern int opt_fstack_limit_register_no;
|
||||
extern bool flag_stack_protector_set_by_fhardened_p;
|
||||
|
||||
/* Input file names. */
|
||||
|
||||
|
|
|
@ -2670,6 +2670,13 @@ DEFHOOK
|
|||
bool, (int fcode),
|
||||
default_libc_has_fast_function)
|
||||
|
||||
DEFHOOK
|
||||
(fortify_source_default_level,
|
||||
"This hook determines what value _FORTIFY_SOURCE will be set to when using\n\
|
||||
the command-line option -fhardened.",
|
||||
unsigned, (void),
|
||||
default_fortify_source_default_level)
|
||||
|
||||
DEFHOOK
|
||||
(libm_function_max_error,
|
||||
"This hook determines expected maximum errors for math functions measured\n\
|
||||
|
|
|
@ -1906,6 +1906,14 @@ bsd_libc_has_function (enum function_class fn_class,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* By default, -fhardened will add -D_FORTIFY_SOURCE=2. */
|
||||
|
||||
unsigned
|
||||
default_fortify_source_default_level ()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
unsigned
|
||||
default_libm_function_max_error (unsigned, machine_mode, bool)
|
||||
{
|
||||
|
|
|
@ -219,6 +219,7 @@ extern bool default_libc_has_fast_function (int fcode);
|
|||
extern bool no_c99_libc_has_function (enum function_class, tree);
|
||||
extern bool gnu_libc_has_function (enum function_class, tree);
|
||||
extern bool bsd_libc_has_function (enum function_class, tree);
|
||||
extern unsigned default_fortify_source_default_level (void);
|
||||
extern unsigned default_libm_function_max_error (unsigned, machine_mode, bool);
|
||||
extern unsigned glibc_linux_libm_function_max_error (unsigned, machine_mode,
|
||||
bool);
|
||||
|
|
6
gcc/testsuite/c-c++-common/fhardened-1.S
Normal file
6
gcc/testsuite/c-c++-common/fhardened-1.S
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* { dg-do preprocess { target { { *-*-linux* *-*-gnu* } && pie } } } */
|
||||
/* { dg-options "-fhardened -O" } */
|
||||
|
||||
#if __PIE__ != 2
|
||||
# error "-fPIE not enabled"
|
||||
#endif
|
14
gcc/testsuite/c-c++-common/fhardened-1.c
Normal file
14
gcc/testsuite/c-c++-common/fhardened-1.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O" } */
|
||||
|
||||
#ifndef __SSP_STRONG__
|
||||
# error "-fstack-protector-strong not enabled"
|
||||
#endif
|
||||
|
||||
#if _FORTIFY_SOURCE < 2
|
||||
# error "_FORTIFY_SOURCE not enabled"
|
||||
#endif
|
||||
|
||||
#ifndef _GLIBCXX_ASSERTIONS
|
||||
# error "_GLIBCXX_ASSERTIONS not enabled"
|
||||
#endif
|
12
gcc/testsuite/c-c++-common/fhardened-10.c
Normal file
12
gcc/testsuite/c-c++-common/fhardened-10.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -D_FORTIFY_SOURCE=1" } */
|
||||
|
||||
#if _FORTIFY_SOURCE != 1
|
||||
# error "_FORTIFY_SOURCE != 1"
|
||||
#endif
|
||||
|
||||
#ifndef _GLIBCXX_ASSERTIONS
|
||||
# error "_GLIBCXX_ASSERTIONS disabled when it should not be"
|
||||
#endif
|
||||
|
||||
/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
|
10
gcc/testsuite/c-c++-common/fhardened-11.c
Normal file
10
gcc/testsuite/c-c++-common/fhardened-11.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O -D_FORTIFY_SOURCE_ -D_GLIBCXX_ASSERTIONS_" } */
|
||||
|
||||
#ifndef _FORTIFY_SOURCE
|
||||
# error "_FORTIFY_SOURCE disabled when it should not be"
|
||||
#endif
|
||||
|
||||
#ifndef _GLIBCXX_ASSERTIONS
|
||||
# error "_GLIBCXX_ASSERTIONS disabled when it should not be"
|
||||
#endif
|
11
gcc/testsuite/c-c++-common/fhardened-12.c
Normal file
11
gcc/testsuite/c-c++-common/fhardened-12.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O -fdump-tree-gimple" } */
|
||||
|
||||
int
|
||||
foo ()
|
||||
{
|
||||
int i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */
|
6
gcc/testsuite/c-c++-common/fhardened-13.c
Normal file
6
gcc/testsuite/c-c++-common/fhardened-13.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
|
||||
/* { dg-options "-fhardened -O" } */
|
||||
|
||||
#if __PIE__ != 2
|
||||
# error "-fPIE not enabled"
|
||||
#endif
|
6
gcc/testsuite/c-c++-common/fhardened-14.c
Normal file
6
gcc/testsuite/c-c++-common/fhardened-14.c
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
|
||||
/* { dg-options "-fhardened -O -fno-PIE" } */
|
||||
|
||||
#ifdef __PIE__
|
||||
# error "PIE enabled when it should not be"
|
||||
#endif
|
5
gcc/testsuite/c-c++-common/fhardened-15.c
Normal file
5
gcc/testsuite/c-c++-common/fhardened-15.c
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-require-stack-check "specific" } */
|
||||
/* { dg-options "-fhardened -O -fstack-check" } */
|
||||
|
||||
/* { dg-warning ".-fstack-clash-protection. is not enabled by .-fhardened. because .-fstack-check. was specified" "" { target *-*-* } 0 } */
|
12
gcc/testsuite/c-c++-common/fhardened-2.c
Normal file
12
gcc/testsuite/c-c++-common/fhardened-2.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -fstack-protector" } */
|
||||
|
||||
#ifdef __SSP_STRONG__
|
||||
# error "-fstack-protector-strong enabled when it should not be"
|
||||
#endif
|
||||
#ifndef __SSP__
|
||||
# error "-fstack-protector not enabled"
|
||||
#endif
|
||||
|
||||
/* { dg-warning ".-fstack-protector-strong. is not enabled" "" { target *-*-* } 0 } */
|
||||
/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
|
14
gcc/testsuite/c-c++-common/fhardened-3.c
Normal file
14
gcc/testsuite/c-c++-common/fhardened-3.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O0" } */
|
||||
/* Test that we don't get any diagnostic coming from libc headers. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* The most useful C program known to man. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
}
|
||||
|
||||
/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
|
4
gcc/testsuite/c-c++-common/fhardened-4.c
Normal file
4
gcc/testsuite/c-c++-common/fhardened-4.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O0 -Wno-hardened" } */
|
||||
|
||||
/* { dg-bogus "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
|
11
gcc/testsuite/c-c++-common/fhardened-5.c
Normal file
11
gcc/testsuite/c-c++-common/fhardened-5.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O -fdump-tree-gimple" } */
|
||||
|
||||
int
|
||||
foo ()
|
||||
{
|
||||
int i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */
|
12
gcc/testsuite/c-c++-common/fhardened-6.c
Normal file
12
gcc/testsuite/c-c++-common/fhardened-6.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -O -ftrivial-auto-var-init=uninitialized -fdump-tree-gimple" } */
|
||||
|
||||
int
|
||||
foo ()
|
||||
{
|
||||
int i;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not ".DEFERRED_INIT" "gimple" } } */
|
||||
/* { dg-warning ".-ftrivial-auto-var-init=zero. is not enabled" "" { target *-*-* } 0 } */
|
7
gcc/testsuite/c-c++-common/fhardened-7.c
Normal file
7
gcc/testsuite/c-c++-common/fhardened-7.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
|
||||
/* { dg-options "-fhardened -O -fpie" } */
|
||||
|
||||
/* -fpie takes precedence over -fhardened */
|
||||
#if __PIE__ != 1
|
||||
# error "__PIE__ != 1"
|
||||
#endif
|
7
gcc/testsuite/c-c++-common/fhardened-8.c
Normal file
7
gcc/testsuite/c-c++-common/fhardened-8.c
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* { dg-do compile { target { { *-*-linux* *-*-gnu* } && pie } } } */
|
||||
/* { dg-options "-fhardened -O -fPIC" } */
|
||||
|
||||
/* -fPIC takes precedence over -fhardened */
|
||||
#ifdef __PIE__
|
||||
# error "PIE enabled when it should not be"
|
||||
#endif
|
9
gcc/testsuite/c-c++-common/fhardened-9.c
Normal file
9
gcc/testsuite/c-c++-common/fhardened-9.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* { dg-do compile { target *-*-linux* *-*-gnu* } } */
|
||||
/* { dg-options "-fhardened -U_FORTIFY_SOURCE -U_GLIBCXX_ASSERTIONS" } */
|
||||
|
||||
#if defined(_FORTIFY_SOURCE) || defined(_GLIBCXX_ASSERTIONS)
|
||||
# error "hardening enabled when it should not be"
|
||||
#endif
|
||||
|
||||
/* { dg-warning "._FORTIFY_SOURCE. is not enabled" "" { target *-*-* } 0 } */
|
||||
/* { dg-warning "._GLIBCXX_ASSERTIONS. is not enabled" "" { target *-*-* } 0 } */
|
|
@ -151,6 +151,8 @@ foreach cls { "ada" "c" "c++" "d" "fortran" "go" \
|
|||
# Listing only excludes gives empty results.
|
||||
check_for_options c "--help=^joined,^separate" "" "" ""
|
||||
|
||||
check_for_options c "--help=hardened" "The following options are enabled by -fhardened" "" ""
|
||||
|
||||
if [ info exists prev_columns ] {
|
||||
# Reset the enviroment variable to its oriuginal value.
|
||||
set env(COLUMNS) $prev_columns
|
||||
|
|
12
gcc/testsuite/gcc.target/i386/cf_check-6.c
Normal file
12
gcc/testsuite/gcc.target/i386/cf_check-6.c
Normal file
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fhardened -mno-manual-endbr" } */
|
||||
/* { dg-final { scan-assembler-times {\mendbr} 1 } } */
|
||||
/* Test that -fhardened enables CET. */
|
||||
|
||||
extern void bar (void) __attribute__((__cf_check__));
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
bar ();
|
||||
}
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Reference in a new issue