GCC: Add a new option "-fstack-protector-strong"
This includes additional functions to be protected: those that have local array definitions, or have references to local frame addresses. This is a new option in GCC-4.9 that was relicensed by Han Shen from Google under GPLv2 for OpenBSD. Obtained from: OpenBSD (2014-01-14) MFC after: 2 weeks
This commit is contained in:
parent
52a7aa675b
commit
b1425be92a
@ -553,7 +553,9 @@ c_cpp_builtins (cpp_reader *pfile)
|
||||
/* Make the choice of the stack protector runtime visible to source code.
|
||||
The macro names and values here were chosen for compatibility with an
|
||||
earlier implementation, i.e. ProPolice. */
|
||||
if (flag_stack_protect == 2)
|
||||
if (flag_stack_protect == 3)
|
||||
cpp_define (pfile, "__SSP_STRONG__=3");
|
||||
else if (flag_stack_protect == 2)
|
||||
cpp_define (pfile, "__SSP_ALL__=2");
|
||||
else if (flag_stack_protect == 1)
|
||||
cpp_define (pfile, "__SSP__=1");
|
||||
|
@ -810,6 +810,12 @@ clear_tree_used (tree block)
|
||||
clear_tree_used (t);
|
||||
}
|
||||
|
||||
enum {
|
||||
SPCT_FLAG_DEFAULT = 1,
|
||||
SPCT_FLAG_ALL = 2,
|
||||
SPCT_FLAG_STRONG = 3
|
||||
};
|
||||
|
||||
/* Examine TYPE and determine a bit mask of the following features. */
|
||||
|
||||
#define SPCT_HAS_LARGE_CHAR_ARRAY 1
|
||||
@ -879,7 +885,8 @@ stack_protect_decl_phase (tree decl)
|
||||
if (bits & SPCT_HAS_SMALL_CHAR_ARRAY)
|
||||
has_short_buffer = true;
|
||||
|
||||
if (flag_stack_protect == 2)
|
||||
if (flag_stack_protect == SPCT_FLAG_ALL
|
||||
|| flag_stack_protect == SPCT_FLAG_STRONG)
|
||||
{
|
||||
if ((bits & (SPCT_HAS_SMALL_CHAR_ARRAY | SPCT_HAS_LARGE_CHAR_ARRAY))
|
||||
&& !(bits & SPCT_HAS_AGGREGATE))
|
||||
@ -947,12 +954,36 @@ create_stack_guard (void)
|
||||
cfun->stack_protect_guard = guard;
|
||||
}
|
||||
|
||||
/* Helper routine to check if a record or union contains an array field. */
|
||||
|
||||
static int
|
||||
record_or_union_type_has_array_p (tree tree_type)
|
||||
{
|
||||
tree fields = TYPE_FIELDS (tree_type);
|
||||
tree f;
|
||||
|
||||
for (f = fields; f; f = TREE_CHAIN (f))
|
||||
if (TREE_CODE (f) == FIELD_DECL)
|
||||
{
|
||||
tree field_type = TREE_TYPE (f);
|
||||
if ((TREE_CODE (field_type) == RECORD_TYPE
|
||||
|| TREE_CODE (field_type) == UNION_TYPE
|
||||
|| TREE_CODE (field_type) == QUAL_UNION_TYPE)
|
||||
&& record_or_union_type_has_array_p (field_type))
|
||||
return 1;
|
||||
if (TREE_CODE (field_type) == ARRAY_TYPE)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Expand all variables used in the function. */
|
||||
|
||||
static void
|
||||
expand_used_vars (void)
|
||||
{
|
||||
tree t, outer_block = DECL_INITIAL (current_function_decl);
|
||||
bool gen_stack_protect_signal = false;
|
||||
|
||||
/* Compute the phase of the stack frame for this function. */
|
||||
{
|
||||
@ -972,6 +1003,29 @@ expand_used_vars (void)
|
||||
has_protected_decls = false;
|
||||
has_short_buffer = false;
|
||||
|
||||
if (flag_stack_protect == SPCT_FLAG_STRONG)
|
||||
for (t = cfun->unexpanded_var_list; t; t = TREE_CHAIN (t))
|
||||
{
|
||||
tree var = TREE_VALUE (t);
|
||||
if (!is_global_var (var))
|
||||
{
|
||||
tree var_type = TREE_TYPE (var);
|
||||
/* Examine local referenced variables that have their addresses
|
||||
* taken, contain an array, or are arrays. */
|
||||
if (TREE_CODE (var) == VAR_DECL
|
||||
&& (TREE_CODE (var_type) == ARRAY_TYPE
|
||||
|| TREE_ADDRESSABLE (var)
|
||||
|| ((TREE_CODE (var_type) == RECORD_TYPE
|
||||
|| TREE_CODE (var_type) == UNION_TYPE
|
||||
|| TREE_CODE (var_type) == QUAL_UNION_TYPE)
|
||||
&& record_or_union_type_has_array_p (var_type))))
|
||||
{
|
||||
gen_stack_protect_signal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point all variables on the unexpanded_var_list with TREE_USED
|
||||
set are not associated with any block scope. Lay them out. */
|
||||
for (t = cfun->unexpanded_var_list; t; t = TREE_CHAIN (t))
|
||||
@ -1032,12 +1086,26 @@ expand_used_vars (void)
|
||||
dump_stack_var_partition ();
|
||||
}
|
||||
|
||||
/* There are several conditions under which we should create a
|
||||
stack guard: protect-all, alloca used, protected decls present. */
|
||||
if (flag_stack_protect == 2
|
||||
|| (flag_stack_protect
|
||||
&& (current_function_calls_alloca || has_protected_decls)))
|
||||
switch (flag_stack_protect)
|
||||
{
|
||||
case SPCT_FLAG_ALL:
|
||||
create_stack_guard ();
|
||||
break;
|
||||
|
||||
case SPCT_FLAG_STRONG:
|
||||
if (gen_stack_protect_signal
|
||||
|| current_function_calls_alloca || has_protected_decls)
|
||||
create_stack_guard ();
|
||||
break;
|
||||
|
||||
case SPCT_FLAG_DEFAULT:
|
||||
if (current_function_calls_alloca || has_protected_decls)
|
||||
create_stack_guard();
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
/* Assign rtl to each variable based on these partitions. */
|
||||
if (stack_vars_num > 0)
|
||||
|
@ -878,6 +878,10 @@ fstack-protector-all
|
||||
Common Report RejectNegative Var(flag_stack_protect, 2) VarExists
|
||||
Use a stack protection method for every function
|
||||
|
||||
fstack-protector-strong
|
||||
Common Report RejectNegative Var(flag_stack_protect, 3)
|
||||
Use a smart stack protection method for certain functions
|
||||
|
||||
fstrength-reduce
|
||||
Common
|
||||
Does nothing. Preserved for backward compatibility.
|
||||
|
@ -2134,6 +2134,10 @@ use.
|
||||
This macro is defined, with value 2, when @option{-fstack-protector-all} is
|
||||
in use.
|
||||
|
||||
@item __SSP_STRONG__
|
||||
This macro is defined, with value 3, when @option{-fstack-protector-strong} is
|
||||
in use.
|
||||
|
||||
@item __TIMESTAMP__
|
||||
This macro expands to a string constant that describes the date and time
|
||||
of the last modification of the current source file. The string constant
|
||||
|
@ -339,7 +339,7 @@ in the following sections.
|
||||
\&\fB\-fsched2\-use\-superblocks
|
||||
\&\-fsched2\-use\-traces \-fsee \-freschedule\-modulo\-scheduled\-loops
|
||||
\&\-fsection\-anchors \-fsignaling\-nans \-fsingle\-precision\-constant
|
||||
\&\-fstack\-protector \-fstack\-protector\-all
|
||||
\&\-fstack\-protector \-fstack\-protector\-all \-fstack\-protector\-strong
|
||||
\&\-fstrict\-aliasing \-fstrict\-overflow \-ftracer \-fthread\-jumps
|
||||
\&\-funroll\-all\-loops \-funroll\-loops \-fpeel\-loops
|
||||
\&\-fsplit\-ivs\-in\-unroller \-funswitch\-loops
|
||||
@ -5193,6 +5193,11 @@ If a guard check fails, an error message is printed and the program exits.
|
||||
.IP "\fB\-fstack\-protector\-all\fR" 4
|
||||
.IX Item "-fstack-protector-all"
|
||||
Like \fB\-fstack\-protector\fR except that all functions are protected.
|
||||
.IP "\fB\-fstack\-protector\-strong\fR" 4
|
||||
.IX Item "-fstack-protector-strong"
|
||||
Like \fB\-fstack\-protector\fR but includes additional functions to
|
||||
be protected \-\-\- those that have local array definitions, or have
|
||||
references to local frame addresses.
|
||||
.IP "\fB\-fsection\-anchors\fR" 4
|
||||
.IX Item "-fsection-anchors"
|
||||
Try to reduce the number of symbolic address calculations by using
|
||||
|
@ -331,7 +331,7 @@ in the following sections.
|
||||
-fsched2-use-superblocks @gol
|
||||
-fsched2-use-traces -fsee -freschedule-modulo-scheduled-loops @gol
|
||||
-fsection-anchors -fsignaling-nans -fsingle-precision-constant @gol
|
||||
-fstack-protector -fstack-protector-all @gol
|
||||
-fstack-protector -fstack-protector-all -fstack-protector-strong @gol
|
||||
-fstrict-aliasing -fstrict-overflow -ftracer -fthread-jumps @gol
|
||||
-funroll-all-loops -funroll-loops -fpeel-loops @gol
|
||||
-fsplit-ivs-in-unroller -funswitch-loops @gol
|
||||
@ -5810,6 +5810,11 @@ If a guard check fails, an error message is printed and the program exits.
|
||||
@item -fstack-protector-all
|
||||
Like @option{-fstack-protector} except that all functions are protected.
|
||||
|
||||
@item -fstack-protector-strong
|
||||
Like @option{-fstack-protector} but includes additional functions to
|
||||
be protected --- those that have local array definitions, or have
|
||||
references to local frame addresses.
|
||||
|
||||
@item -fsection-anchors
|
||||
@opindex fsection-anchors
|
||||
Try to reduce the number of symbolic address calculations by using
|
||||
|
@ -680,7 +680,7 @@ proper position among the other output files. */
|
||||
#ifdef TARGET_LIBC_PROVIDES_SSP
|
||||
#define LINK_SSP_SPEC "%{fstack-protector:}"
|
||||
#else
|
||||
#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared -lssp}"
|
||||
#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-strong|fstack-protector-all:-lssp_nonshared -lssp}"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user