diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2016-12-26 10:08:54 +0100 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2016-12-26 10:10:58 +0100 |
commit | 66a704c43cfec810fea67a6959f2d1c94f4d594f (patch) | |
tree | 174dece4f1f3b73874398c029f8aa96911632e9d | |
parent | bc174f20b83d19167ecac14ce0762eddbe47cc64 (diff) | |
download | glibc-66a704c43cfec810fea67a6959f2d1c94f4d594f.tar.gz glibc-66a704c43cfec810fea67a6959f2d1c94f4d594f.tar.xz glibc-66a704c43cfec810fea67a6959f2d1c94f4d594f.zip |
Work even with compilers which enable -fstack-protector by default [BZ #7065]
With all the machinery we just added, we can easily arrange to work even when the compiler passes in -fstack-protector automatically: all the necessary bits of glibc are always compiled with -fno-stack-protector now. So tear out the check in configure, and add appropriate calls to -fno-stack-protector in tests that need them (largely those that use -nostdlib), since we don't yet have a __stack_chk_fail that those tests can rely upon. (GCC often provides one, but we cannot rely on this, especially not when bootstrapping.) When stack protection is disabled, explicitly pass -fno-stack-protector to everything, to stop a compiler hacked to enable it from inserting calls to __stack_chk_fail via the PLT in every object file.
-rw-r--r-- | ChangeLog | 21 | ||||
-rw-r--r-- | aclocal.m4 | 6 | ||||
-rwxr-xr-x | configure | 90 | ||||
-rw-r--r-- | configure.ac | 75 |
4 files changed, 73 insertions, 119 deletions
diff --git a/ChangeLog b/ChangeLog index ae58d91110..5e3e64a3da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,27 @@ 2016-12-26 Nick Alcock <nick.alcock@oracle.com> [BZ #7065] + * configure.ac: Add check for unsupported stack-protection level. + (libc_cv_predef_stack_protector): Remove. + (no_ssp): New variable. + (STACK_PROTECTOR_LEVEL): Set to zero when --disable-stack-protector. + (stack_protector): Set to -fno-stack-protector similarly. + (libc_cv_ld_gnu_indirect_function): Use no_ssp. + (libc_cv_asm_set_directive): Likewise. + (libc_cv_protected_data): Likewise. + (libc_cv_z_combreloc): Likewise. + (libc_cv_hashstyle): Likewise. + (libc_cv_has_glob_dat): Likewise. + (libc_cv_output_format): Likewise. + (libc_cv_output_format): Likewise. + (libc_cv_ehdr_start): Likewise. + * aclocal.m4 (LIBC_TRY_LINK_STATIC): Likewise. + (LIBC_LINKER_FEATURE): Likewise. + (LIBC_COMPILER_BUILTIN_INLINED): Likewise. + +2016-12-26 Nick Alcock <nick.alcock@oracle.com> + + [BZ #7065] * elf/Makefile (dummy-stack-chk-fail): New. (librtld.map): Use it. diff --git a/aclocal.m4 b/aclocal.m4 index 3d64f7773d..69021558af 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -141,7 +141,7 @@ int _start (void) { return 0; } int __start (void) { return 0; } $1 EOF -AS_IF([AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest +AS_IF([AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -o conftest conftest.c -static -nostartfiles -nostdlib 1>&AS_MESSAGE_LOG_FD])], [$2], [$3]) @@ -226,7 +226,7 @@ if test x"$gnu_ld" = x"yes"; then cat > conftest.c <<EOF int _start (void) { return 42; } EOF - if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS + if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp $2 -nostdlib -nostartfiles -fPIC -shared -o conftest.so conftest.c 1>&AS_MESSAGE_LOG_FD]) @@ -268,7 +268,7 @@ libc_compiler_builtin_inlined=no cat > conftest.c <<EOF int _start (void) { $2 return 0; } EOF -if ! AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS +if ! AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp $3 -nostdlib -nostartfiles -S conftest.c -o - | fgrep "$1" 1>&AS_MESSAGE_LOG_FD]) diff --git a/configure b/configure index b3007953ea..c88f6fe88c 100755 --- a/configure +++ b/configure @@ -4010,11 +4010,25 @@ elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes stack_protector="-fstack-protector-strong" $as_echo "#define STACK_PROTECTOR_LEVEL 3" >>confdefs.h +else + stack_protector="-fno-stack-protector" + $as_echo "#define STACK_PROTECTOR_LEVEL 0" >>confdefs.h + fi +if test -n "$stack_protector"; then + no_ssp=-fno-stack-protector +else + no_ssp= + + if test "$enable_stack_protector" != no; then + as_fn_error $? "--enable-stack-protector=$enable_stack_protector specified, but specified level of stack protection is not supported by the compiler." "$LINENO" 5 + fi +fi + # For the multi-arch option we need support in the assembler & linker. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for assembler and linker STT_GNU_IFUNC support" >&5 $as_echo_n "checking for assembler and linker STT_GNU_IFUNC support... " >&6; } @@ -4037,7 +4051,7 @@ __start: EOF libc_cv_ld_gnu_indirect_function=no if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.S 1>&5 2>&5; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&5 @@ -5532,7 +5546,7 @@ extern int glibc_conftest_frobozz; void _start() { glibc_conftest_frobozz = 1; } EOF if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.s conftest1.c 1>&5 2>&5; then libc_cv_asm_set_directive=yes else @@ -5556,7 +5570,7 @@ else int bar __attribute__ ((visibility ("protected"))) = 1; EOF libc_cv_protected_data=no - if { ac_try='${CC-cc} -nostdlib -nostartfiles -fPIC -shared conftest.c -o conftest.so' + if { ac_try='${CC-cc} -nostdlib -nostartfiles $no_ssp -fPIC -shared conftest.c -o conftest.so' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5566,7 +5580,7 @@ EOF extern int bar; int main (void) { return bar; } EOF - if { ac_try='${CC-cc} -nostdlib -nostartfiles conftest.c -o conftest conftest.so' + if { ac_try='${CC-cc} -nostdlib -nostartfiles $no_ssp conftest.c -o conftest conftest.so' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 ac_status=$? @@ -5651,7 +5665,7 @@ __attribute__ ((constructor)) void ctor (void) { asm (""); } __attribute__ ((destructor)) void dtor (void) { asm (""); } EOF -if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -o conftest +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -o conftest conftest.c -static -nostartfiles -nostdlib 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 @@ -5764,7 +5778,7 @@ extern int mumble; int foo (void) { return bar (mumble); } EOF if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS - -fPIC -shared -o conftest.so conftest.c + -fPIC -shared $no_ssp -o conftest.so conftest.c -nostdlib -nostartfiles -Wl,-z,combreloc 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 @@ -5800,7 +5814,7 @@ if test x"$gnu_ld" = x"yes"; then cat > conftest.c <<EOF int _start (void) { return 42; } EOF - if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS + if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -Wl,-z,execstack -nostdlib -nostartfiles -fPIC -shared -o conftest.so conftest.c 1>&5' @@ -5854,7 +5868,7 @@ else cat > conftest.c <<EOF int _start (void) { return 42; } EOF -if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -fPIC -shared -o conftest.so conftest.c -Wl,--hash-style=both -nostdlib 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 @@ -5947,7 +5961,7 @@ int foo (void) { return mumble; } EOF if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIC -shared -o conftest.so conftest.c - -nostdlib -nostartfiles + -nostdlib -nostartfiles $no_ssp 1>&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 (eval $ac_try) 2>&5 @@ -5975,7 +5989,7 @@ if ${libc_cv_output_format+:} false; then : $as_echo_n "(cached) " >&6 else if libc_cv_output_format=` -${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&5` +${CC-cc} -nostartfiles -nostdlib $no_ssp -Wl,--print-output-format 2>&5` then : else @@ -6453,60 +6467,6 @@ if test $libc_cv_predef_fortify_source = yes; then fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC implicitly enables -fstack-protector" >&5 -$as_echo_n "checking whether $CC implicitly enables -fstack-protector... " >&6; } -if ${libc_cv_predef_stack_protector+:} false; then : - $as_echo_n "(cached) " >&6 -else - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -extern void foobar (char *); -int -main () -{ -char large_array[2048]; foobar (large_array); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -libc_undefs=`$NM -u conftest.o | - LC_ALL=C $AWK '$1 == "U" { print $2 | "sort -u"; next } { exit(1) }' \ - 2>&5` || { - as_fn_error $? "confusing output from $NM -u" "$LINENO" 5 -} -echo >&5 "libc_undefs='$libc_undefs'" -# On some architectures, there are architecture-specific undefined -# symbols (resolved by the linker), so filter out unknown symbols. -# This will fail to produce the correct result if the compiler -# defaults to -fstack-protector but this produces an undefined symbol -# other than __stack_chk_fail or __stack_chk_fail_local. However, -# compilers like that have not been encountered in practice. -libc_undefs=`echo "$libc_undefs" | \ - egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'` -case "$libc_undefs" in -foobar) libc_cv_predef_stack_protector=no ;; -'__stack_chk_fail -foobar'|'__stack_chk_fail_local -foobar') libc_cv_predef_stack_protector=yes ;; -*) as_fn_error $? "unexpected symbols in test: $libc_undefs" "$LINENO" 5 ;; -esac -else - as_fn_error $? "test compilation failed" "$LINENO" 5 -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_predef_stack_protector" >&5 -$as_echo "$libc_cv_predef_stack_protector" >&6; } -libc_extra_cflags= -if test $libc_cv_predef_stack_protector = yes; then - libc_extra_cflags="$libc_extra_cflags -fno-stack-protector" -fi -libc_extra_cppflags= - # Some linkers on some architectures support __ehdr_start but with # bugs. Make sure usage of it does not create relocations in the # output (as the linker should resolve them all for us). @@ -6520,7 +6480,7 @@ old_CFLAGS="$CFLAGS" old_LDFLAGS="$LDFLAGS" old_LIBS="$LIBS" CFLAGS="$CFLAGS -fPIC" -LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared" +LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp" LIBS= cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ diff --git a/configure.ac b/configure.ac index f5fa1aaefa..2782bfaf08 100644 --- a/configure.ac +++ b/configure.ac @@ -665,11 +665,26 @@ elif test "$enable_stack_protector" = all && test "$libc_cv_ssp_all" = yes; then elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes; then stack_protector="-fstack-protector-strong" AC_DEFINE(STACK_PROTECTOR_LEVEL, 3) +else + stack_protector="-fno-stack-protector" + AC_DEFINE(STACK_PROTECTOR_LEVEL, 0) fi AC_SUBST(libc_cv_ssp) AC_SUBST(stack_protector) AC_SUBST(no_stack_protector) +if test -n "$stack_protector"; then + dnl Don't run configure tests with stack-protection on, to avoid problems with + dnl bootstrapping. + no_ssp=-fno-stack-protector +else + no_ssp= + + if test "$enable_stack_protector" != no; then + AC_MSG_ERROR([--enable-stack-protector=$enable_stack_protector specified, but specified level of stack protection is not supported by the compiler.]) + fi +fi + # For the multi-arch option we need support in the assembler & linker. AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support], libc_cv_ld_gnu_indirect_function, [dnl @@ -689,7 +704,7 @@ __start: EOF libc_cv_ld_gnu_indirect_function=no if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.S 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then # Do a link to see if the backend supports IFUNC relocs. $READELF -r conftest 1>&AS_MESSAGE_LOG_FD @@ -1213,7 +1228,7 @@ extern int glibc_conftest_frobozz; void _start() { glibc_conftest_frobozz = 1; } EOF if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \ - -nostartfiles -nostdlib \ + -nostartfiles -nostdlib $no_ssp \ -o conftest conftest.s conftest1.c 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then libc_cv_asm_set_directive=yes else @@ -1230,12 +1245,12 @@ AC_CACHE_CHECK(linker support for protected data symbol, int bar __attribute__ ((visibility ("protected"))) = 1; EOF libc_cv_protected_data=no - if AC_TRY_COMMAND(${CC-cc} -nostdlib -nostartfiles -fPIC -shared conftest.c -o conftest.so); then + if AC_TRY_COMMAND(${CC-cc} -nostdlib -nostartfiles $no_ssp -fPIC -shared conftest.c -o conftest.so); then cat > conftest.c <<EOF extern int bar; int main (void) { return bar; } EOF - if AC_TRY_COMMAND(${CC-cc} -nostdlib -nostartfiles conftest.c -o conftest conftest.so); then + if AC_TRY_COMMAND(${CC-cc} -nostdlib -nostartfiles $no_ssp conftest.c -o conftest conftest.so); then libc_cv_protected_data=yes fi fi @@ -1357,7 +1372,7 @@ extern int mumble; int foo (void) { return bar (mumble); } EOF if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS - -fPIC -shared -o conftest.so conftest.c + -fPIC -shared $no_ssp -o conftest.so conftest.c -nostdlib -nostartfiles -Wl,-z,combreloc 1>&AS_MESSAGE_LOG_FD]) then @@ -1395,7 +1410,7 @@ AC_CACHE_CHECK(for --hash-style option, cat > conftest.c <<EOF int _start (void) { return 42; } EOF -if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS $no_ssp -fPIC -shared -o conftest.so conftest.c -Wl,--hash-style=both -nostdlib 1>&AS_MESSAGE_LOG_FD]) then @@ -1467,7 +1482,7 @@ int foo (void) { return mumble; } EOF if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS -fPIC -shared -o conftest.so conftest.c - -nostdlib -nostartfiles + -nostdlib -nostartfiles $no_ssp 1>&AS_MESSAGE_LOG_FD]) then dnl look for GLOB_DAT relocation. @@ -1484,7 +1499,7 @@ AC_SUBST(libc_cv_has_glob_dat) AC_CACHE_CHECK(linker output format, libc_cv_output_format, [dnl if libc_cv_output_format=` -${CC-cc} -nostartfiles -nostdlib -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD` +${CC-cc} -nostartfiles -nostdlib $no_ssp -Wl,--print-output-format 2>&AS_MESSAGE_LOG_FD` then : else @@ -1703,48 +1718,6 @@ if test $libc_cv_predef_fortify_source = yes; then fi AC_SUBST(CPPUNDEFS) -dnl Check for silly hacked compilers inserting -fstack-protector. -dnl This breaks badly for the early startup code we compile, since -dnl the compiled code can refer to a magic machine-dependent location -dnl for the canary value before we have sufficient setup for that to -dnl work. It's also questionable to build all of libc with this flag -dnl even when you're doing that for most applications you build, since -dnl libc's code is so heavily-used and performance-sensitive. If we -dnl ever really want to make that work, it should be enabled explicitly -dnl in the libc build, not inherited from implicit compiler settings. -AC_CACHE_CHECK([whether $CC implicitly enables -fstack-protector], - libc_cv_predef_stack_protector, [ -AC_TRY_COMPILE([extern void foobar (char *);], - [char large_array[2048]; foobar (large_array);], [ -libc_undefs=`$NM -u conftest.o | - LC_ALL=C $AWK '$1 == "U" { print $2 | "sort -u"; next } { exit(1) }' \ - 2>&AS_MESSAGE_LOG_FD` || { - AC_MSG_ERROR([confusing output from $NM -u]) -} -echo >&AS_MESSAGE_LOG_FD "libc_undefs='$libc_undefs'" -# On some architectures, there are architecture-specific undefined -# symbols (resolved by the linker), so filter out unknown symbols. -# This will fail to produce the correct result if the compiler -# defaults to -fstack-protector but this produces an undefined symbol -# other than __stack_chk_fail or __stack_chk_fail_local. However, -# compilers like that have not been encountered in practice. -libc_undefs=`echo "$libc_undefs" | \ - egrep '^(foobar|__stack_chk_fail|__stack_chk_fail_local)$'` -case "$libc_undefs" in -foobar) libc_cv_predef_stack_protector=no ;; -'__stack_chk_fail -foobar'|'__stack_chk_fail_local -foobar') libc_cv_predef_stack_protector=yes ;; -*) AC_MSG_ERROR([unexpected symbols in test: $libc_undefs]) ;; -esac], - [AC_MSG_ERROR([test compilation failed])]) -]) -libc_extra_cflags= -if test $libc_cv_predef_stack_protector = yes; then - libc_extra_cflags="$libc_extra_cflags -fno-stack-protector" -fi -libc_extra_cppflags= - # Some linkers on some architectures support __ehdr_start but with # bugs. Make sure usage of it does not create relocations in the # output (as the linker should resolve them all for us). @@ -1754,7 +1727,7 @@ old_CFLAGS="$CFLAGS" old_LDFLAGS="$LDFLAGS" old_LIBS="$LIBS" CFLAGS="$CFLAGS -fPIC" -LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared" +LDFLAGS="$LDFLAGS -nostdlib -nostartfiles -shared $no_ssp" LIBS= AC_LINK_IFELSE([AC_LANG_SOURCE([ typedef struct { |