diff options
Diffstat (limited to 'lang')
-rw-r--r-- | lang/gcc/files/patch-stackprotector-gcc | 157 | ||||
-rw-r--r-- | lang/gcc/files/patch-stackprotector-gcc_c-family | 11 | ||||
-rw-r--r-- | lang/gcc/files/patch-stackprotector-gcc_doc | 39 | ||||
-rw-r--r-- | lang/gcc/files/patch-stackprotector-gcc_testsuite | 176 |
4 files changed, 383 insertions, 0 deletions
diff --git a/lang/gcc/files/patch-stackprotector-gcc b/lang/gcc/files/patch-stackprotector-gcc new file mode 100644 index 000000000000..115df78141a7 --- /dev/null +++ b/lang/gcc/files/patch-stackprotector-gcc @@ -0,0 +1,157 @@ +--- gcc/cfgexpand.c.orig ++++ gcc/cfgexpand.c +@@ -1291,6 +1291,12 @@ + 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 +@@ -1360,7 +1366,8 @@ + 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)) +@@ -1514,6 +1521,27 @@ + return size; + } + ++/* Helper routine to check if a record or union contains an array field. */ ++ ++static int ++record_or_union_type_has_array_p (const_tree tree_type) ++{ ++ tree fields = TYPE_FIELDS (tree_type); ++ tree f; ++ ++ for (f = fields; f; f = DECL_CHAIN (f)) ++ if (TREE_CODE (f) == FIELD_DECL) ++ { ++ tree field_type = TREE_TYPE (f); ++ if (RECORD_OR_UNION_TYPE_P (field_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 rtx +@@ -1525,6 +1553,7 @@ + struct pointer_map_t *ssa_name_decls; + unsigned i; + unsigned len; ++ bool gen_stack_protect_signal = false; + + /* Compute the phase of the stack frame for this function. */ + { +@@ -1575,6 +1604,24 @@ + } + } + pointer_map_destroy (ssa_name_decls); ++ ++ if (flag_stack_protect == SPCT_FLAG_STRONG) ++ FOR_EACH_LOCAL_DECL (cfun, i, var) ++ 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) ++ || (RECORD_OR_UNION_TYPE_P (var_type) ++ && record_or_union_type_has_array_p (var_type)))) ++ { ++ gen_stack_protect_signal = true; ++ break; ++ } ++ } + + /* At this point all variables on the local_decls with TREE_USED + set are not associated with any block scope. Lay them out. */ +@@ -1662,12 +1709,32 @@ + 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 +- && (cfun->calls_alloca || has_protected_decls))) +- create_stack_guard (); ++ /* Create stack guard, if ++ a) "-fstack-protector-all" - always; ++ b) "-fstack-protector-strong" - if there are arrays, memory ++ references to local variables, alloca used, or protected decls present; ++ c) "-fstack-protector" - if alloca used, or protected decls present */ ++ ++ switch (flag_stack_protect) ++ { ++ case SPCT_FLAG_ALL: ++ create_stack_guard (); ++ break; ++ ++ case SPCT_FLAG_STRONG: ++ if (gen_stack_protect_signal ++ || cfun->calls_alloca || has_protected_decls) ++ create_stack_guard (); ++ break; ++ ++ case SPCT_FLAG_DEFAULT: ++ if (cfun->calls_alloca || has_protected_decls) ++ create_stack_guard (); ++ break; ++ ++ default: ++ ; ++ } + + /* Assign rtl to each variable based on these partitions. */ + if (stack_vars_num > 0) +@@ -1688,7 +1755,7 @@ + expand_stack_vars (stack_protect_decl_phase_1, &data); + + /* Phase 2 contains other kinds of arrays. */ +- if (flag_stack_protect == 2) ++ if (flag_stack_protect == SPCT_FLAG_ALL) + expand_stack_vars (stack_protect_decl_phase_2, &data); + } + +--- gcc/common.opt.orig ++++ gcc/common.opt +@@ -1942,6 +1942,10 @@ fstack-protector-all + Common Report RejectNegative Var(flag_stack_protect, 2) + 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 ++ + fstack-usage + Common RejectNegative Var(flag_stack_usage) + Output stack usage information on a per-function basis +--- gcc/gcc.c.orig ++++ gcc/gcc.c +@@ -655,7 +655,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 diff --git a/lang/gcc/files/patch-stackprotector-gcc_c-family b/lang/gcc/files/patch-stackprotector-gcc_c-family new file mode 100644 index 000000000000..2dabcb8abcb4 --- /dev/null +++ b/lang/gcc/files/patch-stackprotector-gcc_c-family @@ -0,0 +1,11 @@ +--- gcc/c-family/c-cppbuiltin.c.orig ++++ gcc/c-family/c-cppbuiltin.c +@@ -888,6 +888,8 @@ 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 == 3) ++ cpp_define (pfile, "__SSP_STRONG__=3"); + if (flag_stack_protect == 2) + cpp_define (pfile, "__SSP_ALL__=2"); + else if (flag_stack_protect == 1) diff --git a/lang/gcc/files/patch-stackprotector-gcc_doc b/lang/gcc/files/patch-stackprotector-gcc_doc new file mode 100644 index 000000000000..cc95c871d849 --- /dev/null +++ b/lang/gcc/files/patch-stackprotector-gcc_doc @@ -0,0 +1,39 @@ +--- gcc/doc/cpp.texi.orig ++++ gcc/doc/cpp.texi +@@ -2349,6 +2349,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 __SANITIZE_ADDRESS__ + This macro is defined, with value 1, when @option{-fsanitize=address} is + in use. +--- gcc/doc/invoke.texi.orig ++++ gcc/doc/invoke.texi +@@ -407,8 +407,8 @@ Objective-C and Objective-C++ Dialects}. + -fsel-sched-pipelining -fsel-sched-pipelining-outer-loops @gol + -fshrink-wrap -fsignaling-nans -fsingle-precision-constant @gol + -fsplit-ivs-in-unroller -fsplit-wide-types -fstack-protector @gol +--fstack-protector-all -fstrict-aliasing -fstrict-overflow @gol +--fthread-jumps -ftracer -ftree-bit-ccp @gol ++-fstack-protector-all -fstack-protector-strong -fstrict-aliasing @gol ++-fstrict-overflow -fthread-jumps -ftracer -ftree-bit-ccp @gol + -ftree-builtin-call-dce -ftree-ccp -ftree-ch @gol + -ftree-coalesce-inline-vars -ftree-coalesce-vars -ftree-copy-prop @gol + -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse @gol +@@ -8957,6 +8957,12 @@ If a guard check fails, an error message is printed and the program exits. + @opindex fstack-protector-all + Like @option{-fstack-protector} except that all functions are protected. + ++@item -fstack-protector-strong ++@opindex 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 diff --git a/lang/gcc/files/patch-stackprotector-gcc_testsuite b/lang/gcc/files/patch-stackprotector-gcc_testsuite new file mode 100644 index 000000000000..443a7b4ef893 --- /dev/null +++ b/lang/gcc/files/patch-stackprotector-gcc_testsuite @@ -0,0 +1,176 @@ +--- /dev/null ++++ gcc/testsuite/g++.dg/fstack-protector-strong.C +@@ -0,0 +1,35 @@ ++/* Test that stack protection is done on chosen functions. */ ++ ++/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ ++/* { dg-options "-O2 -fstack-protector-strong" } */ ++ ++class A ++{ ++public: ++ A() {} ++ ~A() {} ++ void method(); ++ int state; ++}; ++ ++/* Frame address exposed to A::method via "this". */ ++int ++foo1 () ++{ ++ A a; ++ a.method (); ++ return a.state; ++} ++ ++/* Possible destroying foo2's stack via &a. */ ++int ++global_func (A& a); ++ ++/* Frame address exposed to global_func. */ ++int foo2 () ++{ ++ A a; ++ return global_func (a); ++} ++ ++/* { dg-final { scan-assembler-times "stack_chk_fail" 2 } } */ +--- /dev/null ++++ gcc/testsuite/gcc.dg/fstack-protector-strong.c +@@ -0,0 +1,135 @@ ++/* Test that stack protection is done on chosen functions. */ ++ ++/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ ++/* { dg-options "-O2 -fstack-protector-strong" } */ ++ ++#include<string.h> ++#include<stdlib.h> ++ ++extern int g0; ++extern int* pg0; ++int ++goo (int *); ++int ++hoo (int); ++ ++/* Function frame address escaped function call. */ ++int ++foo1 () ++{ ++ int i; ++ return goo (&i); ++} ++ ++struct ArrayStruct ++{ ++ int a; ++ int array[10]; ++}; ++ ++struct AA ++{ ++ int b; ++ struct ArrayStruct as; ++}; ++ ++/* Function frame contains array. */ ++int ++foo2 () ++{ ++ struct AA aa; ++ int i; ++ for (i = 0; i < 10; ++i) ++ { ++ aa.as.array[i] = i * (i-1) + i / 2; ++ } ++ return aa.as.array[5]; ++} ++ ++/* Address computation based on a function frame address. */ ++int ++foo3 () ++{ ++ int a; ++ int *p; ++ p = &a + 5; ++ return goo (p); ++} ++ ++/* Address cast based on a function frame address. */ ++int ++foo4 () ++{ ++ int a; ++ return goo (g0 << 2 ? (int *)(3 * (long)(void *)(&a)) : 0); ++} ++ ++/* Address cast based on a local array. */ ++int ++foo5 () ++{ ++ short array[10]; ++ return goo ((int *)(array + 5)); ++} ++ ++struct BB ++{ ++ int one; ++ int two; ++ int three; ++}; ++ ++/* Address computaton based on a function frame address.*/ ++int ++foo6 () ++{ ++ struct BB bb; ++ return goo (&bb.one + sizeof(int)); ++} ++ ++/* Function frame address escaped via global variable. */ ++int ++foo7 () ++{ ++ int a; ++ pg0 = &a; ++ goo (pg0); ++ return *pg0; ++} ++ ++/* Check that this covers -fstack-protector. */ ++int ++foo8 () ++{ ++ char base[100]; ++ memcpy ((void *)base, (const void *)pg0, 105); ++ return (int)(base[32]); ++} ++ ++/* Check that this covers -fstack-protector. */ ++int ++foo9 () ++{ ++ char* p = alloca (100); ++ return goo ((int *)(p + 50)); ++} ++ ++int ++global2 (struct BB* pbb); ++ ++/* Address taken on struct. */ ++int ++foo10 () ++{ ++ struct BB bb; ++ int i; ++ bb.one = global2 (&bb); ++ for (i = 0; i < 10; ++i) ++ { ++ bb.two = bb.one + bb.two; ++ bb.three = bb.one + bb.two + bb.three; ++ } ++ return bb.three; ++} ++ ++/* { dg-final { scan-assembler-times "stack_chk_fail" 10 } } */ |