about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2016-12-26 10:08:18 +0100
committerFlorian Weimer <fweimer@redhat.com>2016-12-26 10:08:19 +0100
commit03baef1c9cfb396d76cae20a00aee657871e79c4 (patch)
treeed115b828293aa26c4b5f338391286b25eaa955e
parent81e0662e5f2c342ffa413826b7b100d56677b613 (diff)
downloadglibc-03baef1c9cfb396d76cae20a00aee657871e79c4.tar.gz
glibc-03baef1c9cfb396d76cae20a00aee657871e79c4.tar.xz
glibc-03baef1c9cfb396d76cae20a00aee657871e79c4.zip
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.
-rw-r--r--ChangeLog13
-rw-r--r--INSTALL11
-rw-r--r--config.h.in6
-rwxr-xr-xconfigure151
-rw-r--r--configure.ac70
-rw-r--r--manual/install.texi11
6 files changed, 193 insertions, 69 deletions
diff --git a/ChangeLog b/ChangeLog
index 0dd96f2d0f..f1b95e0e79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
 	* README.pretty-printers: Must specify CPPFLAGS-* also.
diff --git a/INSTALL b/INSTALL
index acb622a102..104f36b0bf 100644
--- a/INSTALL
+++ b/INSTALL
@@ -135,6 +135,17 @@ will be used, and CFLAGS sets optimization options for the compiler.
 '--enable-lock-elision=yes'
      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'
      The file 'pt_chown' is a helper binary for 'grantpt' (*note
      Pseudo-Terminals: Allocation.) that is installed setuid root to fix
diff --git a/config.h.in b/config.h.in
index 33757bd553..d96ce0f8cf 100644
--- a/config.h.in
+++ b/config.h.in
@@ -48,6 +48,12 @@
 /* Define if compiler accepts -ftree-loop-distribute-patterns.  */
 #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
    (gcc on ix86 only).  */
 #undef	USE_REGPARMS
diff --git a/configure b/configure
index 10b0fb7069..8c69f09232 100755
--- a/configure
+++ b/configure
@@ -620,7 +620,6 @@ libc_cv_cc_loop_to_function
 libc_cv_cc_submachine
 libc_cv_cc_nofma
 libc_cv_mtls_dialect_gnu2
-stack_protector
 fno_unit_at_a_time
 libc_cv_output_format
 libc_cv_has_glob_dat
@@ -661,6 +660,9 @@ sysdeps_add_ons
 sysnames
 submachine
 multi_arch
+no_stack_protector
+stack_protector
+libc_cv_ssp
 base_machine
 add_on_subdirs
 add_ons
@@ -766,6 +768,7 @@ enable_lock_elision
 enable_add_ons
 enable_hidden_plt
 enable_bind_now
+enable_stack_protector
 enable_static_nss
 enable_force_install
 enable_maintainer_mode
@@ -1427,6 +1430,9 @@ Optional Features:
                           for add-ons if no parameter given
   --disable-hidden-plt    do not hide internal function calls to avoid PLT
   --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]
   --disable-force-install don't force installation of files from this package,
                           even if they are older than the installed files
@@ -3427,6 +3433,18 @@ if test "x$bindnow" = xyes; then
 
 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.
 if test "${enable_static_nss+set}" = set; then :
   enableval=$enable_static_nss; static_nss=$enableval
@@ -3912,6 +3930,89 @@ fi
 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.
 { $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; }
@@ -5915,54 +6016,6 @@ else
 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_n "checking for -mtls-dialect=gnu2... " >&6; }
 if ${libc_cv_mtls_dialect_gnu2+:} false; then :
diff --git a/configure.ac b/configure.ac
index aa6e2d7e56..c159768984 100644
--- a/configure.ac
+++ b/configure.ac
@@ -235,6 +235,18 @@ if test "x$bindnow" = xyes; then
   AC_DEFINE(BIND_NOW)
 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 static NSS modules.
 AC_ARG_ENABLE([static-nss],
@@ -619,6 +631,44 @@ fi
 test -n "$base_machine" || base_machine=$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.
 AC_CACHE_CHECK([for assembler and linker STT_GNU_IFUNC support],
 	       libc_cv_ld_gnu_indirect_function, [dnl
@@ -1461,26 +1511,6 @@ else
 fi
 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,
 [dnl
 cat > conftest.c <<EOF
diff --git a/manual/install.texi b/manual/install.texi
index 35e02ada58..d02e87091f 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -164,6 +164,17 @@ time.  Consult the @file{timezone} subdirectory for more details.
 @item --enable-lock-elision=yes
 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
 @findex grantpt
 @item --enable-pt_chown