Add a no_stack_protector function attribute to localize the effect
of disabling stack protection on a function-by-function level, as opposed to per source file.
This commit is contained in:
parent
e1b3bebc56
commit
b58828d4bd
30
gnu/dist/gcc4/gcc/c-common.c
vendored
30
gnu/dist/gcc4/gcc/c-common.c
vendored
@ -529,6 +529,8 @@ static tree handle_tls_model_attribute (tree *, tree, tree, int,
|
||||
bool *);
|
||||
static tree handle_no_instrument_function_attribute (tree *, tree,
|
||||
tree, int, bool *);
|
||||
static tree handle_no_stack_protector_function_attribute (tree *, tree,
|
||||
tree, int, bool *);
|
||||
static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
|
||||
static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
|
||||
@ -608,6 +610,8 @@ const struct attribute_spec c_common_attribute_table[] =
|
||||
handle_weakref_attribute },
|
||||
{ "no_instrument_function", 0, 0, true, false, false,
|
||||
handle_no_instrument_function_attribute },
|
||||
{ "no_stack_protector", 0, 0, true, false, false,
|
||||
handle_no_stack_protector_function_attribute },
|
||||
{ "malloc", 0, 0, true, false, false,
|
||||
handle_malloc_attribute },
|
||||
{ "returns_twice", 0, 0, true, false, false,
|
||||
@ -5051,6 +5055,32 @@ handle_no_instrument_function_attribute (tree *node, tree name,
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
/* Handle a "no_instrument_function" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
||||
static tree
|
||||
handle_no_stack_protector_function_attribute (tree *node, tree name,
|
||||
tree ARG_UNUSED (args),
|
||||
int ARG_UNUSED (flags),
|
||||
bool *no_add_attrs)
|
||||
{
|
||||
tree decl = *node;
|
||||
|
||||
if (TREE_CODE (decl) != FUNCTION_DECL)
|
||||
{
|
||||
error ("%J%qE attribute applies only to functions", decl, name);
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
else if (DECL_INITIAL (decl))
|
||||
{
|
||||
error ("%Jcan%'t set %qE attribute after definition", decl, name);
|
||||
*no_add_attrs = true;
|
||||
}
|
||||
else
|
||||
DECL_NO_STACK_PROTECTOR_FUNCTION (decl) = 1;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handle a "malloc" attribute; arguments as in
|
||||
struct attribute_spec.handler. */
|
||||
|
12
gnu/dist/gcc4/gcc/cfgexpand.c
vendored
12
gnu/dist/gcc4/gcc/cfgexpand.c
vendored
@ -862,6 +862,9 @@ stack_protect_decl_phase (tree decl)
|
||||
unsigned int bits = stack_protect_classify_type (TREE_TYPE (decl));
|
||||
int ret = 0;
|
||||
|
||||
if (DECL_NO_STACK_PROTECTOR_FUNCTION(decl))
|
||||
return ret;
|
||||
|
||||
if (bits & SPCT_HAS_SMALL_CHAR_ARRAY)
|
||||
has_short_buffer = true;
|
||||
|
||||
@ -939,6 +942,7 @@ static void
|
||||
expand_used_vars (void)
|
||||
{
|
||||
tree t, outer_block = DECL_INITIAL (current_function_decl);
|
||||
bool stack_protect_func = !DECL_NO_STACK_PROTECTOR_FUNCTION (current_function_decl);
|
||||
|
||||
/* Compute the phase of the stack frame for this function. */
|
||||
{
|
||||
@ -1008,7 +1012,7 @@ expand_used_vars (void)
|
||||
|
||||
/* If stack protection is enabled, we don't share space between
|
||||
vulnerable data and non-vulnerable data. */
|
||||
if (flag_stack_protect)
|
||||
if (flag_stack_protect && stack_protect_func)
|
||||
add_stack_protection_conflicts ();
|
||||
|
||||
/* Now that we have collected all stack variables, and have computed a
|
||||
@ -1020,7 +1024,8 @@ expand_used_vars (void)
|
||||
|
||||
/* There are several conditions under which we should create a
|
||||
stack guard: protect-all, alloca used, protected decls present. */
|
||||
if (flag_stack_protect == 2
|
||||
if (stack_protect_func)
|
||||
if (flag_stack_protect == 2
|
||||
|| (flag_stack_protect
|
||||
&& (current_function_calls_alloca || has_protected_decls)))
|
||||
create_stack_guard ();
|
||||
@ -1595,7 +1600,8 @@ tree_expand_cfg (void)
|
||||
expand_used_vars ();
|
||||
|
||||
/* Honor stack protection warnings. */
|
||||
if (warn_stack_protect)
|
||||
if (warn_stack_protect &&
|
||||
!DECL_NO_STACK_PROTECTOR_FUNCTION (current_function_decl))
|
||||
{
|
||||
if (current_function_calls_alloca)
|
||||
warning (0, "not protecting local variables: variable length buffer");
|
||||
|
6
gnu/dist/gcc4/gcc/tree.h
vendored
6
gnu/dist/gcc4/gcc/tree.h
vendored
@ -2680,6 +2680,11 @@ struct tree_decl_non_common GTY(())
|
||||
#define DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(NODE) \
|
||||
(FUNCTION_DECL_CHECK (NODE)->function_decl.no_instrument_function_entry_exit)
|
||||
|
||||
/* Used in FUNCTION_DECLs to indicate that the function should not be stack
|
||||
protected */
|
||||
#define DECL_NO_STACK_PROTECTOR_FUNCTION(NODE) \
|
||||
(FUNCTION_DECL_CHECK (NODE)->function_decl.no_stack_protector_function)
|
||||
|
||||
/* Used in FUNCTION_DECLs to indicate that limit-stack-* should be
|
||||
disabled in this function. */
|
||||
#define DECL_NO_LIMIT_STACK(NODE) \
|
||||
@ -2746,6 +2751,7 @@ struct tree_function_decl GTY(())
|
||||
unsigned regdecl_flag : 1;
|
||||
unsigned inline_flag : 1;
|
||||
unsigned no_instrument_function_entry_exit : 1;
|
||||
unsigned no_stack_protector_function : 1;
|
||||
unsigned no_limit_stack : 1;
|
||||
ENUM_BITFIELD(built_in_class) built_in_class : 2;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user