summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2016-12-26 10:08:54 +0100
committerFlorian Weimer <fweimer@redhat.com>2016-12-26 10:10:58 +0100
commit66a704c43cfec810fea67a6959f2d1c94f4d594f (patch)
tree174dece4f1f3b73874398c029f8aa96911632e9d
parentbc174f20b83d19167ecac14ce0762eddbe47cc64 (diff)
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--ChangeLog21
-rw-r--r--aclocal.m46
-rwxr-xr-xconfigure90
-rw-r--r--configure.ac75
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 {