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.
This commit is contained in:
parent
60b6a5a4d8
commit
df96e42c51
240
configure.ac
240
configure.ac
@ -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],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user