Configure support for --enable-stack-protector [BZ #7065]

This adds =all and =strong, with obvious semantics, defaulting to off.

We don't validate the value of the option yet: that's in a later patch.
Nor do we use it for anything at this stage.

We differentiate between 'the compiler understands -fstack-protector'
and 'the user wanted -fstack-protector' so that we can pass
-fno-stack-protector in appropriate places even if the user didn't want
to turn on -fstack-protector for other parts.  (This helps us overcome
another existing limitation, that glibc doesn't work with GCCs hacked
to pass in -fstack-protector by default.)

We also arrange to set the STACK_PROTECTOR_LEVEL #define to a value
appropriate for the stack-protection level in use for each file in
particular.
This commit is contained in:
Nick Alcock 2016-12-26 10:08:18 +01:00 committed by Florian Weimer
parent 81e0662e5f
commit 03baef1c9c
6 changed files with 193 additions and 69 deletions

View File

@ -1,3 +1,16 @@
2016-12-26 Nick Alcock <nick.alcock@oracle.com>
[BZ #7065]
* configure.ac (libc_cv_ssp): Move up.
(libc_cv_ssp_strong): Likewise.
(libc_cv_ssp_all): New.
(stack_protector): Augment, adding -fstack-protector-all.
(no_stack_protector): New.
(STACK_PROTECTOR_LEVEL): New.
(AC_ARG_ENABLE(stack-protector)): New configure flag.
* manual/install.texi (--enable-stack-protector): Document it.
* config.h.in (STACK_PROTECTOR_LEVEL): New macro.
2016-12-24 Carlos O'Donell <carlos@redhat.com> 2016-12-24 Carlos O'Donell <carlos@redhat.com>
* README.pretty-printers: Must specify CPPFLAGS-* also. * README.pretty-printers: Must specify CPPFLAGS-* also.

11
INSTALL
View File

@ -135,6 +135,17 @@ will be used, and CFLAGS sets optimization options for the compiler.
'--enable-lock-elision=yes' '--enable-lock-elision=yes'
Enable lock elision for pthread mutexes by default. Enable lock elision for pthread mutexes by default.
'--enable-stack-protector'
'--enable-stack-protector=strong'
'--enable-stack-protector=all'
Compile the C library and all other parts of the glibc package
(including the threading and math libraries, NSS modules, and
transliteration modules) using the GCC '-fstack-protector',
'-fstack-protector-strong' or '-fstack-protector-all' options to
detect stack overruns. Only the dynamic linker and a small number
of routines called directly from assembler are excluded from this
protection.
'--enable-pt_chown' '--enable-pt_chown'
The file 'pt_chown' is a helper binary for 'grantpt' (*note The file 'pt_chown' is a helper binary for 'grantpt' (*note
Pseudo-Terminals: Allocation.) that is installed setuid root to fix Pseudo-Terminals: Allocation.) that is installed setuid root to fix

View File

@ -48,6 +48,12 @@
/* Define if compiler accepts -ftree-loop-distribute-patterns. */ /* Define if compiler accepts -ftree-loop-distribute-patterns. */
#undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL #undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
/* The level of stack protection in use for glibc as a whole.
May be overridden on a file-by-file basis. */
#ifndef STACK_PROTECTOR_LEVEL
#undef STACK_PROTECTOR_LEVEL
#endif
/* Define if the regparm attribute shall be used for local functions /* Define if the regparm attribute shall be used for local functions
(gcc on ix86 only). */ (gcc on ix86 only). */
#undef USE_REGPARMS #undef USE_REGPARMS

151
configure vendored
View File

@ -620,7 +620,6 @@ libc_cv_cc_loop_to_function
libc_cv_cc_submachine libc_cv_cc_submachine
libc_cv_cc_nofma libc_cv_cc_nofma
libc_cv_mtls_dialect_gnu2 libc_cv_mtls_dialect_gnu2
stack_protector
fno_unit_at_a_time fno_unit_at_a_time
libc_cv_output_format libc_cv_output_format
libc_cv_has_glob_dat libc_cv_has_glob_dat
@ -661,6 +660,9 @@ sysdeps_add_ons
sysnames sysnames
submachine submachine
multi_arch multi_arch
no_stack_protector
stack_protector
libc_cv_ssp
base_machine base_machine
add_on_subdirs add_on_subdirs
add_ons add_ons
@ -766,6 +768,7 @@ enable_lock_elision
enable_add_ons enable_add_ons
enable_hidden_plt enable_hidden_plt
enable_bind_now enable_bind_now
enable_stack_protector
enable_static_nss enable_static_nss
enable_force_install enable_force_install
enable_maintainer_mode enable_maintainer_mode
@ -1427,6 +1430,9 @@ Optional Features:
for add-ons if no parameter given for add-ons if no parameter given
--disable-hidden-plt do not hide internal function calls to avoid PLT --disable-hidden-plt do not hide internal function calls to avoid PLT
--enable-bind-now disable lazy relocations in DSOs --enable-bind-now disable lazy relocations in DSOs
--enable-stack-protector=[yes|no|all|strong]
Use -fstack-protector[-all|-strong] to detect glibc
buffer overflows
--enable-static-nss build static NSS modules [default=no] --enable-static-nss build static NSS modules [default=no]
--disable-force-install don't force installation of files from this package, --disable-force-install don't force installation of files from this package,
even if they are older than the installed files even if they are older than the installed files
@ -3427,6 +3433,18 @@ if test "x$bindnow" = xyes; then
fi fi
# Check whether --enable-stack-protector was given.
if test "${enable_stack_protector+set}" = set; then :
enableval=$enable_stack_protector; enable_stack_protector=$enableval
else
enable_stack_protector=no
fi
case "$enable_stack_protector" in
all|yes|no|strong) ;;
*) as_fn_error $? "Not a valid argument for --enable-stack-protector: \"$enable_stack_protector\"" "$LINENO" 5;;
esac
# Check whether --enable-static-nss was given. # Check whether --enable-static-nss was given.
if test "${enable_static_nss+set}" = set; then : if test "${enable_static_nss+set}" = set; then :
enableval=$enable_static_nss; static_nss=$enableval enableval=$enable_static_nss; static_nss=$enableval
@ -3912,6 +3930,89 @@ fi
test -n "$base_machine" || base_machine=$machine test -n "$base_machine" || base_machine=$machine
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5
$as_echo_n "checking for -fstack-protector... " >&6; }
if ${libc_cv_ssp+:} false; then :
$as_echo_n "(cached) " >&6
else
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector -xc /dev/null -S -o /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then :
libc_cv_ssp=yes
else
libc_cv_ssp=no
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5
$as_echo "$libc_cv_ssp" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5
$as_echo_n "checking for -fstack-protector-strong... " >&6; }
if ${libc_cv_ssp_strong+:} false; then :
$as_echo_n "(cached) " >&6
else
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-strong -xc /dev/null -S -o /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then :
libc_cv_ssp_strong=yes
else
libc_cv_ssp_strong=no
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_strong" >&5
$as_echo "$libc_cv_ssp_strong" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-all" >&5
$as_echo_n "checking for -fstack-protector-all... " >&6; }
if ${libc_cv_ssp_all+:} false; then :
$as_echo_n "(cached) " >&6
else
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-all -xc /dev/null -S -o /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then :
libc_cv_ssp_all=yes
else
libc_cv_ssp_all=no
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_all" >&5
$as_echo "$libc_cv_ssp_all" >&6; }
stack_protector=
no_stack_protector=
if test "$libc_cv_ssp" = yes; then
no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
fi
if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
stack_protector="-fstack-protector"
$as_echo "#define STACK_PROTECTOR_LEVEL 1" >>confdefs.h
elif test "$enable_stack_protector" = all && test "$libc_cv_ssp_all" = yes; then
stack_protector="-fstack-protector-all"
$as_echo "#define STACK_PROTECTOR_LEVEL 2" >>confdefs.h
elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes; then
stack_protector="-fstack-protector-strong"
$as_echo "#define STACK_PROTECTOR_LEVEL 3" >>confdefs.h
fi
# For the multi-arch option we need support in the assembler & linker. # 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 "$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; } $as_echo_n "checking for assembler and linker STT_GNU_IFUNC support... " >&6; }
@ -5915,54 +6016,6 @@ else
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector" >&5
$as_echo_n "checking for -fstack-protector... " >&6; }
if ${libc_cv_ssp+:} false; then :
$as_echo_n "(cached) " >&6
else
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector -xc /dev/null -S -o /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then :
libc_cv_ssp=yes
else
libc_cv_ssp=no
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp" >&5
$as_echo "$libc_cv_ssp" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -fstack-protector-strong" >&5
$as_echo_n "checking for -fstack-protector-strong... " >&6; }
if ${libc_cv_ssp_strong+:} false; then :
$as_echo_n "(cached) " >&6
else
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -Werror -fstack-protector-strong -xc /dev/null -S -o /dev/null'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then :
libc_cv_ssp_strong=yes
else
libc_cv_ssp_strong=no
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ssp_strong" >&5
$as_echo "$libc_cv_ssp_strong" >&6; }
stack_protector=
if test "$libc_cv_ssp_strong" = "yes"; then
stack_protector="-fstack-protector-strong"
elif test "$libc_cv_ssp" = "yes"; then
stack_protector="-fstack-protector"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -mtls-dialect=gnu2" >&5
$as_echo_n "checking for -mtls-dialect=gnu2... " >&6; } $as_echo_n "checking for -mtls-dialect=gnu2... " >&6; }
if ${libc_cv_mtls_dialect_gnu2+:} false; then : if ${libc_cv_mtls_dialect_gnu2+:} false; then :

View File

@ -235,6 +235,18 @@ if test "x$bindnow" = xyes; then
AC_DEFINE(BIND_NOW) AC_DEFINE(BIND_NOW)
fi fi
dnl Build glibc with -fstack-protector, -fstack-protector-all, or
dnl -fstack-protector-strong.
AC_ARG_ENABLE([stack-protector],
AC_HELP_STRING([--enable-stack-protector=@<:@yes|no|all|strong@:>@],
[Use -fstack-protector[-all|-strong] to detect glibc buffer overflows]),
[enable_stack_protector=$enableval],
[enable_stack_protector=no])
case "$enable_stack_protector" in
all|yes|no|strong) ;;
*) AC_MSG_ERROR([Not a valid argument for --enable-stack-protector: \"$enable_stack_protector\"]);;
esac
dnl On some platforms we cannot use dynamic loading. We must provide dnl On some platforms we cannot use dynamic loading. We must provide
dnl static NSS modules. dnl static NSS modules.
AC_ARG_ENABLE([static-nss], AC_ARG_ENABLE([static-nss],
@ -619,6 +631,44 @@ fi
test -n "$base_machine" || base_machine=$machine test -n "$base_machine" || base_machine=$machine
AC_SUBST(base_machine) AC_SUBST(base_machine)
AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector],
[libc_cv_ssp=yes],
[libc_cv_ssp=no])
])
AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong],
[libc_cv_ssp_strong=yes],
[libc_cv_ssp_strong=no])
])
AC_CACHE_CHECK(for -fstack-protector-all, libc_cv_ssp_all, [dnl
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-all],
[libc_cv_ssp_all=yes],
[libc_cv_ssp_all=no])
])
stack_protector=
no_stack_protector=
if test "$libc_cv_ssp" = yes; then
no_stack_protector="-fno-stack-protector -DSTACK_PROTECTOR_LEVEL=0"
fi
if test "$enable_stack_protector" = yes && test "$libc_cv_ssp" = yes; then
stack_protector="-fstack-protector"
AC_DEFINE(STACK_PROTECTOR_LEVEL, 1)
elif test "$enable_stack_protector" = all && test "$libc_cv_ssp_all" = yes; then
stack_protector="-fstack-protector-all"
AC_DEFINE(STACK_PROTECTOR_LEVEL, 2)
elif test "$enable_stack_protector" = strong && test "$libc_cv_ssp_strong" = yes; then
stack_protector="-fstack-protector-strong"
AC_DEFINE(STACK_PROTECTOR_LEVEL, 3)
fi
AC_SUBST(libc_cv_ssp)
AC_SUBST(stack_protector)
AC_SUBST(no_stack_protector)
# For the multi-arch option we need support in the assembler & linker. # For the multi-arch option we need support in the assembler & linker.
AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support], AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support],
libc_cv_ld_gnu_indirect_function, [dnl libc_cv_ld_gnu_indirect_function, [dnl
@ -1461,26 +1511,6 @@ else
fi fi
AC_SUBST(fno_unit_at_a_time) AC_SUBST(fno_unit_at_a_time)
AC_CACHE_CHECK(for -fstack-protector, libc_cv_ssp, [dnl
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector],
[libc_cv_ssp=yes],
[libc_cv_ssp=no])
])
AC_CACHE_CHECK(for -fstack-protector-strong, libc_cv_ssp_strong, [dnl
LIBC_TRY_CC_OPTION([$CFLAGS $CPPFLAGS -Werror -fstack-protector-strong],
[libc_cv_ssp_strong=yes],
[libc_cv_ssp_strong=no])
])
stack_protector=
if test "$libc_cv_ssp_strong" = "yes"; then
stack_protector="-fstack-protector-strong"
elif test "$libc_cv_ssp" = "yes"; then
stack_protector="-fstack-protector"
fi
AC_SUBST(stack_protector)
AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2, AC_CACHE_CHECK([for -mtls-dialect=gnu2], libc_cv_mtls_dialect_gnu2,
[dnl [dnl
cat > conftest.c <<EOF cat > conftest.c <<EOF

View File

@ -164,6 +164,17 @@ time. Consult the @file{timezone} subdirectory for more details.
@item --enable-lock-elision=yes @item --enable-lock-elision=yes
Enable lock elision for pthread mutexes by default. Enable lock elision for pthread mutexes by default.
@item --enable-stack-protector
@itemx --enable-stack-protector=strong
@itemx --enable-stack-protector=all
Compile the C library and all other parts of the glibc package
(including the threading and math libraries, NSS modules, and
transliteration modules) using the GCC @option{-fstack-protector},
@option{-fstack-protector-strong} or @option{-fstack-protector-all}
options to detect stack overruns. Only the dynamic linker and a small
number of routines called directly from assembler are excluded from this
protection.
@pindex pt_chown @pindex pt_chown
@findex grantpt @findex grantpt
@item --enable-pt_chown @item --enable-pt_chown