diff options
Diffstat (limited to 'm4')
-rw-r--r-- | m4/check-hardening-options.m4 | 109 | ||||
-rw-r--r-- | m4/check-libc.m4 | 169 | ||||
-rw-r--r-- | m4/check-os-options.m4 | 142 | ||||
-rw-r--r-- | m4/disable-compiler-warnings.m4 | 29 |
4 files changed, 449 insertions, 0 deletions
diff --git a/m4/check-hardening-options.m4 b/m4/check-hardening-options.m4 new file mode 100644 index 0000000..3ffdb1a --- /dev/null +++ b/m4/check-hardening-options.m4 @@ -0,0 +1,109 @@ + +AC_DEFUN([CHECK_CFLAG], [ + AC_LANG_ASSERT(C) + AC_MSG_CHECKING([if $saved_CC supports "$1"]) + old_cflags="$CFLAGS" + CFLAGS="$1 -Wall -Werror" + AC_TRY_LINK([ + #include <stdio.h> + ], + [printf("Hello")], + AC_MSG_RESULT([yes]) + CFLAGS=$old_cflags + HARDEN_CFLAGS="$HARDEN_CFLAGS $1", + AC_MSG_RESULT([no]) + CFLAGS=$old_cflags + [$2]) +]) + +AC_DEFUN([CHECK_LDFLAG], [ + AC_LANG_ASSERT(C) + AC_MSG_CHECKING([if $saved_LD supports "$1"]) + old_ldflags="$LDFLAGS" + LDFLAGS="$1 -Wall -Werror" + AC_TRY_LINK([ + #include <stdio.h> + ], + [printf("Hello")], + AC_MSG_RESULT([yes]) + LDFLAGS=$old_ldflags + HARDEN_LDFLAGS="$HARDEN_LDFLAGS $1", + AC_MSG_RESULT([no]) + LDFLAGS=$old_ldflags + [$2]) +]) + +AC_DEFUN([DISABLE_AS_EXECUTABLE_STACK], [ + save_cflags="$CFLAGS" + CFLAGS= + AC_MSG_CHECKING([whether AS supports .note.GNU-stack]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + __asm__(".section .note.GNU-stack,\"\",@progbits");]])], + [AC_MSG_RESULT([yes])] + [AM_CFLAGS=-DHAVE_GNU_STACK], + [AC_MSG_RESULT([no])] + ) + CFLAGS="$save_cflags $AM_CFLAGS" +]) + + +AC_DEFUN([CHECK_C_HARDENING_OPTIONS], [ + + AC_ARG_ENABLE([hardening], + [AS_HELP_STRING([--disable-hardening], + [Disable options to frustrate memory corruption exploits])], + [], [enable_hardening=yes]) + + AC_ARG_ENABLE([windows-ssp], + [AS_HELP_STRING([--enable-windows-ssp], + [Enable building the stack smashing protection on + Windows. This currently distributing libssp-0.dll.])]) + + # We want to check for compiler flag support. Prior to clang v5.1, there was no + # way to make clang's "argument unused" warning fatal. So we invoke the + # compiler through a wrapper script that greps for this message. + saved_CC="$CC" + saved_LD="$LD" + flag_wrap="$srcdir/scripts/wrap-compiler-for-flag-check" + CC="$flag_wrap $CC" + LD="$flag_wrap $LD" + + AS_IF([test "x$enable_hardening" = "xyes"], [ + # Tell GCC to NOT optimize based on signed arithmetic overflow + CHECK_CFLAG([[-fno-strict-overflow]]) + + # _FORTIFY_SOURCE replaces builtin functions with safer versions. + CHECK_CFLAG([[-D_FORTIFY_SOURCE=2]]) + + # Enable read only relocations + CHECK_LDFLAG([[-Wl,-z,relro]]) + CHECK_LDFLAG([[-Wl,-z,now]]) + + # Windows security flags + AS_IF([test "x$HOST_OS" = "xwin"], [ + CHECK_LDFLAG([[-Wl,--nxcompat]]) + CHECK_LDFLAG([[-Wl,--dynamicbase]]) + CHECK_LDFLAG([[-Wl,--high-entropy-va]]) + ]) + + # Use stack-protector-strong if available; if not, fallback to + # stack-protector-all which is considered to be overkill + AS_IF([test "x$enable_windows_ssp" = "xyes" -o "x$HOST_OS" != "xwin"], [ + CHECK_CFLAG([[-fstack-protector-strong]], + CHECK_CFLAG([[-fstack-protector-all]], + AC_MSG_WARN([compiler does not appear to support stack protection]) + ) + ) + AS_IF([test "x$HOST_OS" = "xwin"], [ + AC_SEARCH_LIBS([__stack_chk_guard],[ssp]) + ]) + ]) + ]) + + # Restore CC, LD + CC="$saved_CC" + LD="$saved_LD" + + CFLAGS="$CFLAGS $HARDEN_CFLAGS" + LDFLAGS="$LDFLAGS $HARDEN_LDFLAGS" +]) diff --git a/m4/check-libc.m4 b/m4/check-libc.m4 new file mode 100644 index 0000000..e511f6d --- /dev/null +++ b/m4/check-libc.m4 @@ -0,0 +1,169 @@ +AC_DEFUN([CHECK_LIBC_COMPAT], [ +# Check for libc headers +AC_CHECK_HEADERS([err.h readpassphrase.h]) +# Check for general libc functions +AC_CHECK_FUNCS([asprintf freezero memmem]) +AC_CHECK_FUNCS([readpassphrase reallocarray recallocarray]) +AC_CHECK_FUNCS([strlcat strlcpy strndup strnlen strsep strtonum]) +AC_CHECK_FUNCS([timegm _mkgmtime timespecsub]) +AC_CHECK_FUNCS([getprogname syslog syslog_r]) +AC_CACHE_CHECK([for getpagesize], ac_cv_func_getpagesize, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +// Since Android NDK v16 getpagesize is defined as inline inside unistd.h +#ifdef __ANDROID__ +# include <unistd.h> +#endif + ]], [[ + getpagesize(); +]])], + [ ac_cv_func_getpagesize="yes" ], + [ ac_cv_func_getpagesize="no" + ]) +]) +AM_CONDITIONAL([HAVE_ASPRINTF], [test "x$ac_cv_func_asprintf" = xyes]) +AM_CONDITIONAL([HAVE_FREEZERO], [test "x$ac_cv_func_freezero" = xyes]) +AM_CONDITIONAL([HAVE_GETPAGESIZE], [test "x$ac_cv_func_getpagesize" = xyes]) +AM_CONDITIONAL([HAVE_MEMMEM], [test "x$ac_cv_func_memmem" = xyes]) +AM_CONDITIONAL([HAVE_READPASSPHRASE], [test "x$ac_cv_func_readpassphrase" = xyes]) +AM_CONDITIONAL([HAVE_REALLOCARRAY], [test "x$ac_cv_func_reallocarray" = xyes]) +AM_CONDITIONAL([HAVE_RECALLOCARRAY], [test "x$ac_cv_func_recallocarray" = xyes]) +AM_CONDITIONAL([HAVE_STRLCAT], [test "x$ac_cv_func_strlcat" = xyes]) +AM_CONDITIONAL([HAVE_STRLCPY], [test "x$ac_cv_func_strlcpy" = xyes]) +AM_CONDITIONAL([HAVE_STRNDUP], [test "x$ac_cv_func_strndup" = xyes]) +AM_CONDITIONAL([HAVE_STRNLEN], [test "x$ac_cv_func_strnlen" = xyes]) +AM_CONDITIONAL([HAVE_STRSEP], [test "x$ac_cv_func_strsep" = xyes]) +AM_CONDITIONAL([HAVE_STRTONUM], [test "x$ac_cv_func_strtonum" = xyes]) +AM_CONDITIONAL([HAVE_TIMEGM], [test "x$ac_cv_func_timegm" = xyes]) +AM_CONDITIONAL([HAVE_GETPROGNAME], [test "x$ac_cv_func_getprogname" = xyes]) +AM_CONDITIONAL([HAVE_SYSLOG], [test "x$ac_cv_func_syslog" = xyes]) +AM_CONDITIONAL([HAVE_SYSLOG_R], [test "x$ac_cv_func_syslog_r" = xyes]) +]) + +AC_DEFUN([CHECK_SYSCALL_COMPAT], [ +AC_CHECK_FUNCS([accept4 pipe2 pledge poll socketpair]) +AM_CONDITIONAL([HAVE_ACCEPT4], [test "x$ac_cv_func_accept4" = xyes]) +AM_CONDITIONAL([HAVE_PIPE2], [test "x$ac_cv_func_pipe2" = xyes]) +AM_CONDITIONAL([HAVE_PLEDGE], [test "x$ac_cv_func_pledge" = xyes]) +AM_CONDITIONAL([HAVE_POLL], [test "x$ac_cv_func_poll" = xyes]) +AM_CONDITIONAL([HAVE_SOCKETPAIR], [test "x$ac_cv_func_socketpair" = xyes]) +]) + +AC_DEFUN([CHECK_B64_NTOP], [ +AC_SEARCH_LIBS([b64_ntop],[resolv]) +AC_SEARCH_LIBS([__b64_ntop],[resolv]) +AC_CACHE_CHECK([for b64_ntop], ac_cv_have_b64_ntop_arg, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <resolv.h> + ]], [[ b64_ntop(NULL, 0, NULL, 0); ]])], + [ ac_cv_have_b64_ntop_arg="yes" ], + [ ac_cv_have_b64_ntop_arg="no" + ]) +]) +AM_CONDITIONAL([HAVE_B64_NTOP], [test "x$ac_cv_func_b64_ntop_arg" = xyes]) +]) + +AC_DEFUN([CHECK_CRYPTO_COMPAT], [ +# Check crypto-related libc functions and syscalls +AC_CHECK_FUNCS([arc4random arc4random_buf arc4random_uniform]) +AC_CHECK_FUNCS([explicit_bzero getauxval]) + +AC_CACHE_CHECK([for getentropy], ac_cv_func_getentropy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/types.h> +#include <unistd.h> + +/* + * Explanation: + * + * - iOS <= 10.1 fails because of missing sys/random.h + * + * - in macOS 10.12 getentropy is not tagged as introduced in + * 10.12 so we cannot use it for target < 10.12 + */ +#ifdef __APPLE__ +# include <AvailabilityMacros.h> +# include <TargetConditionals.h> + +# if (TARGET_OS_IPHONE || TARGET_OS_SIMULATOR) +# include <sys/random.h> /* Not available as of iOS <= 10.1 */ +# else + +# include <sys/random.h> /* Pre 10.12 systems should die here */ + +/* Based on: https://gitweb.torproject.org/tor.git/commit/?id=16fcbd21 */ +# ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 /* Robustness */ +# endif +# if defined(MAC_OS_X_VERSION_MIN_REQUIRED) +# if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +# error "Targeting on Mac OSX 10.11 or earlier" +# endif +# endif + +# endif +#endif /* __APPLE__ */ + ]], [[ + char buffer; + (void)getentropy(&buffer, sizeof (buffer)); +]])], + [ ac_cv_func_getentropy="yes" ], + [ ac_cv_func_getentropy="no" + ]) +]) + +AC_CHECK_FUNCS([timingsafe_bcmp timingsafe_memcmp]) +AM_CONDITIONAL([HAVE_ARC4RANDOM], [test "x$ac_cv_func_arc4random" = xyes]) +AM_CONDITIONAL([HAVE_ARC4RANDOM_BUF], [test "x$ac_cv_func_arc4random_buf" = xyes]) +AM_CONDITIONAL([HAVE_ARC4RANDOM_UNIFORM], [test "x$ac_cv_func_arc4random_uniform" = xyes]) +AM_CONDITIONAL([HAVE_EXPLICIT_BZERO], [test "x$ac_cv_func_explicit_bzero" = xyes]) +AM_CONDITIONAL([HAVE_GETENTROPY], [test "x$ac_cv_func_getentropy" = xyes]) +AM_CONDITIONAL([HAVE_TIMINGSAFE_BCMP], [test "x$ac_cv_func_timingsafe_bcmp" = xyes]) +AM_CONDITIONAL([HAVE_TIMINGSAFE_MEMCMP], [test "x$ac_cv_func_timingsafe_memcmp" = xyes]) + +# Override arc4random_buf implementations with known issues +AM_CONDITIONAL([HAVE_ARC4RANDOM_BUF], + [test "x$USE_BUILTIN_ARC4RANDOM" != xyes \ + -a "x$ac_cv_func_arc4random_buf" = xyes]) + +# Check for getentropy fallback dependencies +AC_CHECK_FUNCS([getauxval]) +AC_SEARCH_LIBS([dl_iterate_phdr],[dl]) +AC_CHECK_FUNCS([dl_iterate_phdr]) + +AC_SEARCH_LIBS([pthread_once],[pthread]) +AC_SEARCH_LIBS([pthread_mutex_lock],[pthread]) +AC_SEARCH_LIBS([clock_gettime],[rt posix4]) +AC_CHECK_FUNCS([clock_gettime]) +AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "x$ac_cv_func_clock_gettime" = xyes]) +]) + +AC_DEFUN([CHECK_VA_COPY], [ +AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdarg.h> +va_list x,y; + ]], [[ va_copy(x,y); ]])], + [ ac_cv_have_va_copy="yes" ], + [ ac_cv_have_va_copy="no" + ]) +]) +if test "x$ac_cv_have_va_copy" = "xyes" ; then + AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists]) +fi + +AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdarg.h> +va_list x,y; + ]], [[ __va_copy(x,y); ]])], + [ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no" + ]) +]) +if test "x$ac_cv_have___va_copy" = "xyes" ; then + AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists]) +fi +]) diff --git a/m4/check-os-options.m4 b/m4/check-os-options.m4 new file mode 100644 index 0000000..8241aee --- /dev/null +++ b/m4/check-os-options.m4 @@ -0,0 +1,142 @@ +AC_DEFUN([CHECK_OS_OPTIONS], [ + +CFLAGS="$CFLAGS -Wall -std=gnu99 -fno-strict-aliasing" +BUILD_NC=yes + +case $host_os in + *aix*) + HOST_OS=aix + if test "`echo $CC | cut -d ' ' -f 1`" != "gcc" ; then + CFLAGS="-qnoansialias $USER_CFLAGS" + fi + AC_SUBST([PLATFORM_LDADD], ['-lperfstat']) + ;; + *cygwin*) + HOST_OS=cygwin + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" + ;; + *darwin*) + HOST_OS=darwin + HOST_ABI=macosx + # + # Don't use arc4random on systems before 10.12 because of + # weak seed on failure to open /dev/random, based on latest + # public source: + # http://www.opensource.apple.com/source/Libc/Libc-997.90.3/gen/FreeBSD/arc4random.c + # + # We use the presence of getentropy() to detect 10.12. The + # following check take into account that: + # + # - iOS <= 10.1 fails because of missing getentropy and + # hence they miss sys/random.h + # + # - in macOS 10.12 getentropy is not tagged as introduced in + # 10.12 so we cannot use it for target < 10.12 + # + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <AvailabilityMacros.h> +#include <unistd.h> +#include <sys/random.h> /* Systems without getentropy() should die here */ + +/* Based on: https://gitweb.torproject.org/tor.git/commit/?id=16fcbd21 */ +#ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 +#endif +#if defined(MAC_OS_X_VERSION_MIN_REQUIRED) +# if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +# error "Running on Mac OSX 10.11 or earlier" +# endif +#endif + ]], [[ +char buf[1]; getentropy(buf, 1); + ]])], + [ USE_BUILTIN_ARC4RANDOM=no ], + [ USE_BUILTIN_ARC4RANDOM=yes ] + ) + AC_MSG_CHECKING([whether to use builtin arc4random]) + AC_MSG_RESULT([$USE_BUILTIN_ARC4RANDOM]) + # Not available on iOS + AC_CHECK_HEADER([arpa/telnet.h], [], [BUILD_NC=no]) + ;; + *freebsd*) + HOST_OS=freebsd + HOST_ABI=elf + # fork detection missing, weak seed on failure + # https://svnweb.freebsd.org/base/head/lib/libc/gen/arc4random.c?revision=268642&view=markup + USE_BUILTIN_ARC4RANDOM=yes + AC_SUBST([PROG_LDADD], ['-lthr']) + ;; + *hpux*) + HOST_OS=hpux; + if test "`echo $CC | cut -d ' ' -f 1`" = "gcc" ; then + CFLAGS="$CFLAGS -mlp64" + else + CFLAGS="-g -O2 +DD64 +Otype_safety=off $USER_CFLAGS" + fi + CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D__STRICT_ALIGNMENT" + ;; + *linux*) + HOST_OS=linux + HOST_ABI=elf + CPPFLAGS="$CPPFLAGS -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -D_GNU_SOURCE" + ;; + *midipix*) + HOST_OS=midipix + CPPFLAGS="$CPPFLAGS -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_POSIX_SOURCE -D_GNU_SOURCE" + ;; + *netbsd*) + HOST_OS=netbsd + HOST_ABI=elf + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include <sys/param.h> +#if __NetBSD_Version__ < 700000001 + undefined +#endif + ]], [[]])], + [ USE_BUILTIN_ARC4RANDOM=no ], + [ USE_BUILTIN_ARC4RANDOM=yes ] + ) + CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE" + ;; + *openbsd* | *bitrig*) + HOST_OS=openbsd + HOST_ABI=elf + AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD gcc has bounded]) + AC_DEFINE([HAVE_ATTRIBUTE__DEAD], [1], [OpenBSD gcc has __dead]) + ;; + *mingw*) + HOST_OS=win + HOST_ABI=mingw64 + BUILD_NC=no + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE -D_POSIX -D_POSIX_SOURCE -D__USE_MINGW_ANSI_STDIO" + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_THREAD_SAFE_FUNCTIONS" + CPPFLAGS="$CPPFLAGS -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600" + CPPFLAGS="$CPPFLAGS" + AC_SUBST([PLATFORM_LDADD], ['-lws2_32']) + ;; + *solaris*) + HOST_OS=solaris + HOST_ABI=elf + CPPFLAGS="$CPPFLAGS -D__EXTENSIONS__ -D_XOPEN_SOURCE=600 -DBSD_COMP" + AC_SUBST([PLATFORM_LDADD], ['-ldl -lnsl -lsocket']) + ;; + *) ;; +esac + +AC_ARG_ENABLE([nc], + AS_HELP_STRING([--enable-nc], [Enable installing TLS-enabled nc(1)])) +AM_CONDITIONAL([ENABLE_NC], [test "x$enable_nc" = xyes]) +AM_CONDITIONAL([BUILD_NC], [test x$BUILD_NC = xyes -o "x$enable_nc" = xyes]) + +AM_CONDITIONAL([HOST_AIX], [test x$HOST_OS = xaix]) +AM_CONDITIONAL([HOST_CYGWIN], [test x$HOST_OS = xcygwin]) +AM_CONDITIONAL([HOST_DARWIN], [test x$HOST_OS = xdarwin]) +AM_CONDITIONAL([HOST_FREEBSD], [test x$HOST_OS = xfreebsd]) +AM_CONDITIONAL([HOST_HPUX], [test x$HOST_OS = xhpux]) +AM_CONDITIONAL([HOST_LINUX], [test x$HOST_OS = xlinux]) +AM_CONDITIONAL([HOST_MIDIPIX], [test x$HOST_OS = xmidipix]) +AM_CONDITIONAL([HOST_NETBSD], [test x$HOST_OS = xnetbsd]) +AM_CONDITIONAL([HOST_OPENBSD], [test x$HOST_OS = xopenbsd]) +AM_CONDITIONAL([HOST_SOLARIS], [test x$HOST_OS = xsolaris]) +AM_CONDITIONAL([HOST_WIN], [test x$HOST_OS = xwin]) +]) diff --git a/m4/disable-compiler-warnings.m4 b/m4/disable-compiler-warnings.m4 new file mode 100644 index 0000000..2792722 --- /dev/null +++ b/m4/disable-compiler-warnings.m4 @@ -0,0 +1,29 @@ +AC_DEFUN([DISABLE_COMPILER_WARNINGS], [ +# Clang throws a lot of warnings when it does not understand a flag. Disable +# this warning for now so other warnings are visible. +AC_MSG_CHECKING([if compiling with clang]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#ifndef __clang__ + not clang +#endif + ]])], + [CLANG=yes], + [CLANG=no] +) +AC_MSG_RESULT([$CLANG]) +AS_IF([test "x$CLANG" = "xyes"], [CLANG_FLAGS=-Qunused-arguments]) +CFLAGS="$CFLAGS $CLANG_FLAGS" +LDFLAGS="$LDFLAGS $CLANG_FLAGS" + +# Removing the dependency on -Wno-pointer-sign should be a goal. These are +# largely unsigned char */char* mismatches in asn1 functions. +save_cflags="$CFLAGS" +CFLAGS=-Wno-pointer-sign +AC_MSG_CHECKING([whether CC supports -Wno-pointer-sign]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], + [AC_MSG_RESULT([yes])] + [AM_CFLAGS=-Wno-pointer-sign], + [AC_MSG_RESULT([no])] +) +CFLAGS="$save_cflags $AM_CFLAGS" +]) |