Permalink
Browse files

Added stack protection, PIE, fortify source, etc.

Added various security options that can be enabled at compile time.  These
options include everything that the "hardening-check" script written by Kees
Cook checks for.  After this change, the hardening-check script produces the
following output against the fwknopd binary:

$ hardening-check server/.libs/fwknopd
server/.libs/fwknopd:
 Position Independent Executable: yes
 Stack protected: yes
 Fortify Source functions: yes
 Read-only relocations: yes
 Immediate binding: yes

One of the compile outputs (for example) that shows the new options is:

/bin/bash ../libtool --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I..     -g -O2 -fstack-protector-all -fPIE -pie -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wl,-z,now -MT fko_decode.lo -MD -MP -MF .deps/fko_decode.Tpo -c -o fko_decode.lo fko_decode.c

From the hardening-check man page, here is a description of each of these
options:

NAME
       hardening-check - check binaries for security hardening features

SYNOPSIS
       Examine a given set of ELF binaries and check for several security
       hardening features, failing if they are not all found.

DESCRIPTION
       This utility checks a given list of ELF binaries for several security
       hardening features that can be compiled into an executable.  These
       features are:

       Position Independent Executable
               This indicates that the executable was built in such a way
               (PIE) that the "text" section of the program can be relocated
               in memory.  To take full advantage of this feature, the
               executing kernel must support text Address Space Layout
               Randomization (ASLR).

       Stack Protected
               This indicates that the executable was compiled with the
               gcc(1) option -fstack-protector.  The program will be
               resistant to have its stack overflowed.

       Fortify Source functions
               This indicates that the executable was compiled with
               -D_FORTIFY_SOURCE=2 and -O2 or higher.  This causes certain
               unsafe glibc functions with their safer counterparts (e.g.
               strncpy instead of strcpy).

       Read-only relocations
               This indicates that the executable was build with -Wl,-z,relro
               to have ELF markings (RELRO) that ask the runtime linker to
               mark any regions of the relocation table as "read-only" if
               they were resolved before execution begins.  This reduces the
               possible areas of memory in a program that can be used by an
               attacker that performs a successful memory corruption exploit.

       Immediate binding
               This indicates that the executable was built with -Wl,-z,now
               to have ELF markings (BIND_NOW) that ask the runtime linker to
               resolve all relocations before starting program execution.
               When combined with RELRO above, this further reduces the
               regions of memory available to memory corruption attacks.
  • Loading branch information...
1 parent 60b6a5a commit df96e42c51b6847d91575dfd68f8cb23ba3aa318 @mrash committed Aug 18, 2011
Showing with 230 additions and 10 deletions.
  1. +230 −10 configure.ac
View
@@ -82,6 +82,41 @@ AS_IF([test "$want_file_cache" = yes], [
AC_DEFINE([USE_FILE_CACHE], [1], [Define this to enable non-gdbm/ndbm digest storing (eliminates gdbm/ndbm dependency).])
])
+use_stack_protector=yes
+AC_ARG_ENABLE(stackprotect,
+ [ --without-stackprotect Don't use compiler's stack protection], [
+ if test "x$withval" = "xno"; then
+ use_stack_protector=no
+ fi ])
+
+use_pie=yes
+AC_ARG_ENABLE(pie,
+ [ --without-pie Do not use Position Independent Executables], [
+ if test "x$withval" = "xno"; then
+ use_pie=no
+ fi ])
+
+use_fortify_source=yes
+AC_ARG_ENABLE(fortify_source,
+ [ --without-fortify-source Do not fortify source functions], [
+ if test "x$withval" = "xno"; then
+ use_fortify_source=no
+ fi ])
+
+use_ro_relocations=yes
+AC_ARG_ENABLE(ro_relocations,
+ [ --without-ro-relocations Do not use read-only relocation protection], [
+ if test "x$withval" = "xno"; then
+ use_ro_relocations=no
+ fi ])
+
+use_immediate_binding=yes
+AC_ARG_ENABLE(immediate_binding,
+ [ --without-immediate-binding Do not use immediate binding protection], [
+ if test "x$withval" = "xno"; then
+ use_immediate_binding=no
+ fi ])
+
AC_GNU_SOURCE
AC_PROG_CC
@@ -96,16 +131,18 @@ AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PROG_LIBTOOL
-# It seems we need to add these for (at least my) FreeBSD system.
-# (--DSS TOD): See if we can either make this conditional on OS or
-# add the search path at check time).
-#
-if [ test "x$CPPFLAGS" = "x" ] ; then
- CPPFLAGS="-I/usr/local/include -I/usr/local/include/gpgme"
-fi
-if [ test "x$LDFLAGS" = "x" ] ; then
- LDFLAGS="-L/usr/local/lib"
-fi
+case "$host" in
+*-*-linux*)
+ ;;
+*-*-freebsd*)
+ if [ test "x$CPPFLAGS" = "x" ] ; then
+ CPPFLAGS="-I/usr/local/include -I/usr/local/include/gpgme"
+ fi
+ if [ test "x$LDFLAGS" = "x" ] ; then
+ LDFLAGS="-L/usr/local/lib"
+ fi
+ ;;
+esac
# Checks for header files.
#
@@ -149,6 +186,189 @@ AC_CHECK_FUNCS([bzero gettimeofday memmove memset socket strchr strcspn strdup s
AC_SEARCH_LIBS([socket], [socket])
AC_SEARCH_LIBS([inet_addr], [nsl])
+# Check for security features offered by the compiler
+#
+
+# From OpenSSH:
+# -fstack-protector-all doesn't always work for some GCC versions
+# and/or platforms, so we test if we can. If it's not supported
+# on a given platform gcc will emit a warning so we use -Werror.
+if test "x$use_stack_protector" = "xyes"; then
+# for t in "-fstack-protector-all" "-fstack-protector" "-fPIE -pie" "-D_FORTIFY_SOURCE=2" "-O2" "-Wl,-z,now"; do
+ for t in -fstack-protector-all -fstack-protector; do
+ AC_MSG_CHECKING(if $CC supports $t)
+ saved_CFLAGS="$CFLAGS"
+ saved_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS $t -Werror"
+ LDFLAGS="$LDFLAGS $t -Werror"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ CFLAGS="$saved_CFLAGS $t"
+ LDFLAGS="$saved_LDFLAGS $t"
+ AC_MSG_CHECKING(if $t works)
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ break ],
+ [ AC_MSG_RESULT(no) ],
+ [ AC_MSG_WARN([cross compiling: cannot test])
+ break ]
+ )
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LDFLAGS="$saved_LDFLAGS"
+ done
+fi
+
+if test "x$use_pie" = "xyes"; then
+ for t in "-fPIE -pie"; do
+ AC_MSG_CHECKING(if $CC supports $t)
+ saved_CFLAGS="$CFLAGS"
+ saved_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS $t -Werror"
+ LDFLAGS="$LDFLAGS $t -Werror"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ CFLAGS="$saved_CFLAGS $t"
+ LDFLAGS="$saved_LDFLAGS $t"
+ AC_MSG_CHECKING(if $t works)
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ break ],
+ [ AC_MSG_RESULT(no) ],
+ [ AC_MSG_WARN([cross compiling: cannot test])
+ break ]
+ )
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LDFLAGS="$saved_LDFLAGS"
+ done
+fi
+
+if test "x$use_fortify_source" = "xyes"; then
+ for t in "-D_FORTIFY_SOURCE=2"; do
+ AC_MSG_CHECKING(if $CC supports $t)
+ saved_CFLAGS="$CFLAGS"
+ saved_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS $t -Werror"
+ LDFLAGS="$LDFLAGS $t -Werror"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ CFLAGS="$saved_CFLAGS $t"
+ LDFLAGS="$saved_LDFLAGS $t"
+ AC_MSG_CHECKING(if $t works)
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ break ],
+ [ AC_MSG_RESULT(no) ],
+ [ AC_MSG_WARN([cross compiling: cannot test])
+ break ]
+ )
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LDFLAGS="$saved_LDFLAGS"
+ done
+fi
+
+if test "x$use_ro_relocations" = "xyes"; then
+ for t in "-Wl,-z,relro"; do
+ AC_MSG_CHECKING(if $CC supports $t)
+ saved_CFLAGS="$CFLAGS"
+ saved_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS $t -Werror"
+ LDFLAGS="$LDFLAGS $t -Werror"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ CFLAGS="$saved_CFLAGS $t"
+ LDFLAGS="$saved_LDFLAGS $t"
+ AC_MSG_CHECKING(if $t works)
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ break ],
+ [ AC_MSG_RESULT(no) ],
+ [ AC_MSG_WARN([cross compiling: cannot test])
+ break ]
+ )
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LDFLAGS="$saved_LDFLAGS"
+ done
+fi
+
+if test "x$use_immediate_binding" = "xyes"; then
+ for t in "-Wl,-z,now"; do
+ AC_MSG_CHECKING(if $CC supports $t)
+ saved_CFLAGS="$CFLAGS"
+ saved_LDFLAGS="$LDFLAGS"
+ CFLAGS="$CFLAGS $t -Werror"
+ LDFLAGS="$LDFLAGS $t -Werror"
+ AC_LINK_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ CFLAGS="$saved_CFLAGS $t"
+ LDFLAGS="$saved_LDFLAGS $t"
+ AC_MSG_CHECKING(if $t works)
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
+#include <stdio.h>
+int main(void){char x[[256]]; snprintf(x, sizeof(x), "NNN"); return 0;}
+ ])],
+ [ AC_MSG_RESULT(yes)
+ break ],
+ [ AC_MSG_RESULT(no) ],
+ [ AC_MSG_WARN([cross compiling: cannot test])
+ break ]
+ )
+ ],
+ [ AC_MSG_RESULT(no) ]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LDFLAGS="$saved_LDFLAGS"
+ done
+fi
+
# Check for 3rd-party libs
#
AC_ARG_WITH([gpgme],

0 comments on commit df96e42

Please sign in to comment.