summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/gcc_stack_protect.m442
-rw-r--r--configure.ac77
2 files changed, 109 insertions, 10 deletions
diff --git a/common/gcc_stack_protect.m4 b/common/gcc_stack_protect.m4
index 616101e..13c5e0a 100644
--- a/common/gcc_stack_protect.m4
+++ b/common/gcc_stack_protect.m4
@@ -6,19 +6,23 @@ dnl * Stricter language checking (C or C++)
dnl * Adds GCC_STACK_PROTECT_LIB to add -lssp to LDFLAGS as necessary
dnl * Caches all results
dnl * Uses macros to ensure correct ouput in quiet/silent mode
+dnl 1.2 - April 2007 - Ted Percival <ted@midg3t.net>
+dnl * Added GCC_STACK_PROTECTOR macro for simpler (one-line) invocation
+dnl * GCC_STACK_PROTECT_LIB now adds -lssp to LIBS rather than LDFLAGS
dnl
dnl About ssp:
dnl GCC extension for protecting applications from stack-smashing attacks
dnl http://www.research.ibm.com/trl/projects/security/ssp/
dnl
dnl Usage:
-dnl Call GCC_STACK_PROTECT_LIB to determine if the library implementing SSP is
-dnl available, then the appropriate C or C++ language's test. If you are using
-dnl both C and C++ you will need to use AC_LANG_PUSH and AC_LANG_POP to ensure
-dnl the right language is being used for each test.
+dnl Most people will simply call GCC_STACK_PROTECTOR.
+dnl If you only use one of C or C++, you can save time by only calling the
+dnl macro appropriate for that language. In that case you should also call
+dnl GCC_STACK_PROTECT_LIB first.
dnl
-dnl GCC_STACK_PROTECT_LIB
-dnl adds libssp to the LDFLAGS if it is available
+dnl GCC_STACK_PROTECTOR
+dnl Tries to turn on stack protection for C and C++ by calling the following
+dnl three macros with the right languages.
dnl
dnl GCC_STACK_PROTECT_CC
dnl checks -fstack-protector with the C compiler, if it exists then updates
@@ -28,16 +32,22 @@ dnl GCC_STACK_PROTECT_CXX
dnl checks -fstack-protector with the C++ compiler, if it exists then updates
dnl CXXFLAGS and defines ENABLE_SSP_CXX
dnl
+dnl GCC_STACK_PROTECT_LIB
+dnl adds -lssp to LIBS if it is available
+dnl ssp is usually provided as part of libc, but was previously a separate lib
+dnl It does not hurt to add -lssp even if libc provides SSP - in that case
+dnl libssp will simply be ignored.
+dnl
AC_DEFUN([GCC_STACK_PROTECT_LIB],[
AC_CACHE_CHECK([whether libssp exists], ssp_cv_lib,
- [ssp_old_ldflags="$LDFLAGS"
- LDFLAGS="$LDFLAGS -lssp"
+ [ssp_old_libs="$LIBS"
+ LIBS="$LIBS -lssp"
AC_TRY_LINK(,, ssp_cv_lib=yes, ssp_cv_lib=no)
- LDFLAGS="$ssp_old_ldflags"
+ LIBS="$ssp_old_libs"
])
if test $ssp_cv_lib = yes; then
- LDFLAGS="$LDFLAGS -lssp"
+ LIBS="$LIBS -lssp"
fi
])
@@ -75,3 +85,15 @@ AC_DEFUN([GCC_STACK_PROTECT_CXX],[
fi
])
+AC_DEFUN([GCC_STACK_PROTECTOR],[
+ GCC_STACK_PROTECT_LIB
+
+ AC_LANG_PUSH([C])
+ GCC_STACK_PROTECT_CC
+ AC_LANG_POP([C])
+
+ AC_LANG_PUSH([C++])
+ GCC_STACK_PROTECT_CXX
+ AC_LANG_POP([C++])
+])
+
diff --git a/configure.ac b/configure.ac
index d9d4f42..81954a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -56,6 +56,79 @@ AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_GCC_TRADITIONAL
+# -fstack-protector
+AC_ARG_ENABLE([stack-protector],
+ [AS_HELP_STRING([--disable-stack-protector],
+ [Disable GCC's/libc's stack-smashing protection])],
+ [case "${enableval}" in
+ yes) enable_ssp=yes ;;
+ no) enable_ssp=no ;;
+ *) AC_MSG_ERROR([invalid value ${enableval} for --disable-stack-protector]) ;;
+ esac],
+ [enable_ssp=yes])
+
+if test x"$enable_ssp" = x"yes" && test x"$GCC" != x"yes"; then
+ AC_MSG_NOTICE([Disabling stack-smashing protection because compiler is not GCC])
+ enable_ssp=no
+fi
+
+if test x"$enable_ssp" = x"yes"; then
+ # Check for broken ssp in libc: http://www.avahi.org/ticket/105
+ # libc's brokenness will get in the way regardless of whether -lssp is
+ # provided, but provide it anyway (otherwise non-libc ssp would wrongly
+ # break here)
+
+ # Get -lssp if it exists
+ GCC_STACK_PROTECT_LIB
+
+ AC_MSG_CHECKING([whether stack-smashing protection is available])
+ ssp_old_cflags="$CFLAGS"
+ ssp_old_ldflags="$LDFLAGS"
+ CFLAGS="$CFLAGS -fstack-protector-all -fPIC"
+ LDFLAGS="$LDFLAGS -Wl,-z,defs"
+ cat confdefs.h > conftest.c
+ cat >>conftest.c <<_ACEOF
+void test_broken_ssp(c)
+ const char *c;
+{
+ char arr[[123]], *p; /* beware of possible double-braces if copying this */
+ for (p = arr; *c; ++p) {
+ *p = *c;
+ ++c;
+ }
+}
+_ACEOF
+ rm -f conftest.o
+
+ if $CC -c $CFLAGS $CPPFLAGS -o conftest.o conftest.c >/dev/null 2>&1; then
+ AC_MSG_RESULT([yes])
+ AC_MSG_CHECKING([whether stack-smashing protection is buggy])
+ if $CC -o conftest.so $LDFLAGS -shared conftest.o $LIBS >/dev/null 2>&1; then
+ AC_MSG_RESULT([no])
+ else
+ AC_MSG_RESULT([yes])
+ enable_ssp=no
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+
+ rm -f conftest.c conftest.o conftest.so
+
+ CFLAGS="$ssp_old_cflags"
+ LDFLAGS="$ssp_old_ldflags"
+fi
+
+if test x"$enable_ssp" = x"yes"; then
+ # Do this the long way so we don't call GCC_STACK_PROTECT_LIB twice
+ GCC_STACK_PROTECT_CC
+
+ AC_LANG_PUSH([C++])
+ GCC_STACK_PROTECT_CXX
+ AC_LANG_POP([C++])
+ # XXX: Update the enable_ssp value now for output later?
+fi
+
# libtool stuff
AC_PROG_LIBTOOL
@@ -959,6 +1032,7 @@ echo "
Group for avahi-autoipd: ${AVAHI_AUTOIPD_GROUP}
Enable chroot(): ${enable_chroot}
Enable Linux inotify: ${have_inotify}
+ Enable stack-smashing protection: ${enable_ssp}
"
BUILD_DAEMON="no (You need libdaemon and expat!)"
@@ -985,6 +1059,9 @@ fi
if test "x$ENABLE_COMPAT_HOWL" = "xyes" -a "x$BUILD_CLIENT" != "xyes" ; then
ENABLE_COMPAT_HOWL="no (You need libavahi-client!)"
fi
+if test "x$ENABLE_AUTOIPD" = "xyes" -a "x$HAVE_LIBDAEMON" != "xyes" ; then
+ ENABLE_AUTOIPD="no (You need libdaemon!)"
+fi
BUILD_UI="no"
if test "x$HAVE_GTK" = "xyes" -a "x$BUILD_CLIENT" = "xyes" ; then