diff options
-rw-r--r-- | common/gcc_stack_protect.m4 | 42 | ||||
-rw-r--r-- | configure.ac | 77 |
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 |