Date: Tue, 10 Jun 2014 02:11:30 +0000 (UTC) From: Gerald Pfeifer <gerald@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r357238 - in head/lang/gcc48: . files Message-ID: <201406100211.s5A2BUL3074892@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gerald Date: Tue Jun 10 02:11:30 2014 New Revision: 357238 URL: http://svnweb.freebsd.org/changeset/ports/357238 QAT: https://qat.redports.org/buildarchive/r357238/ Log: Update to the 20140605 snapshot of GCC 4.8.4. Add support for "-fstack-protector-strong". This extends the WITH_SSP_PORTS Makefile option in FreeBSD which adds "-fstack-protector" and "-fstack-protector-all" command-line options that add extra code to check for buffer overflows to ports built that way, cf. https://gcc.gnu.org/onlinedocs/gcc-4.8.3/gcc/Optimize-Options.html While this was a good first step, those switches offer too little protection or too much overhead and so Google contributed a balanced "-fstack-protector-strong". [1] PR: 186852 [1] Submitted by: software-freebsd@interfasys.ch [1] Added: head/lang/gcc48/files/patch-stackprotector-gcc (contents, props changed) head/lang/gcc48/files/patch-stackprotector-gcc_c-family (contents, props changed) head/lang/gcc48/files/patch-stackprotector-gcc_doc (contents, props changed) head/lang/gcc48/files/patch-stackprotector-gcc_testsuite (contents, props changed) Modified: head/lang/gcc48/Makefile head/lang/gcc48/distinfo Modified: head/lang/gcc48/Makefile ============================================================================== --- head/lang/gcc48/Makefile Tue Jun 10 02:02:29 2014 (r357237) +++ head/lang/gcc48/Makefile Tue Jun 10 02:11:30 2014 (r357238) @@ -2,7 +2,7 @@ # $FreeBSD$ PORTNAME= gcc48 -PORTVERSION= 4.8.4.s20140522 +PORTVERSION= 4.8.4.s20140605 CATEGORIES= lang java MASTER_SITES= ${MASTER_SITE_GCC} MASTER_SITE_SUBDIR= snapshots/${DISTVERSION} Modified: head/lang/gcc48/distinfo ============================================================================== --- head/lang/gcc48/distinfo Tue Jun 10 02:02:29 2014 (r357237) +++ head/lang/gcc48/distinfo Tue Jun 10 02:11:30 2014 (r357238) @@ -1,2 +1,2 @@ -SHA256 (gcc-4.8-20140522.tar.bz2) = e09e1c56f85b3ea8b9f109a142d6acc63f50764b43c3ab105e3885ba8aeec4c0 -SIZE (gcc-4.8-20140522.tar.bz2) = 81947405 +SHA256 (gcc-4.8-20140605.tar.bz2) = d66f6f4569654d53209ec30c477459e9e2b1f9ffe6cf116e0a1a6c7010da1c59 +SIZE (gcc-4.8-20140605.tar.bz2) = 81932422 Added: head/lang/gcc48/files/patch-stackprotector-gcc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lang/gcc48/files/patch-stackprotector-gcc Tue Jun 10 02:11:30 2014 (r357238) @@ -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 Added: head/lang/gcc48/files/patch-stackprotector-gcc_c-family ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lang/gcc48/files/patch-stackprotector-gcc_c-family Tue Jun 10 02:11:30 2014 (r357238) @@ -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) Added: head/lang/gcc48/files/patch-stackprotector-gcc_doc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lang/gcc48/files/patch-stackprotector-gcc_doc Tue Jun 10 02:11:30 2014 (r357238) @@ -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 Added: head/lang/gcc48/files/patch-stackprotector-gcc_testsuite ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/lang/gcc48/files/patch-stackprotector-gcc_testsuite Tue Jun 10 02:11:30 2014 (r357238) @@ -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 } } */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201406100211.s5A2BUL3074892>