diff --git a/.travis.yml b/.travis.yml index fc122e77..63d21eda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ matrix: - COMPILER=clang script: - autoreconf -i - - ./configure --enable-docker --disable-dns --disable-sodium + - ./configure --enable-docker --disable-dns --disable-sodium --enable-asan --enable-ubsan - cd docker - make regression-$COMPILER - cd .. diff --git a/common/Makefile.am b/common/Makefile.am index 4bdd2f3f..097f07e7 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -1,4 +1,22 @@ -AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(EXT_CFLAGS) $(libsodium_CFLAGS) $(GETDNS_CFLAGS) $(JSON11_CFLAGS) $(LIBCURL_CFLAGS) $(LIBCRYPTO_INCLUDES) $(YAMLCPP_FLAGS) $(GEOIP_CFLAGS) $(MMDB_CFLAGS) -O3 -Wall -pthread -DSYSCONFDIR='"$(sysconfdir)"' +AM_CPPFLAGS = \ + $(LUA_CFLAGS) \ + $(YAHTTP_CFLAGS) \ + $(EXT_CFLAGS) \ + $(libsodium_CFLAGS) \ + $(GETDNS_CFLAGS) \ + $(JSON11_CFLAGS) \ + $(LIBCURL_CFLAGS) \ + $(LIBCRYPTO_INCLUDES) \ + $(YAMLCPP_FLAGS) \ + $(GEOIP_CFLAGS) \ + $(MMDB_CFLAGS) \ + -pthread \ + -DSYSCONFDIR='"$(sysconfdir)"' \ + $(SANITIZER_FLAGS) + +AM_LDFLAGS = \ + $(PROGRAM_LDFLAGS) \ + $(SANITIZER_FLAGS) noinst_LTLIBRARIES=libweakforce.la libweakforce_la_LIBADD=$(EXT_LIBS) $(YAHTTP_LIBS) $(JSON11_LIBS) $(BOOST_FILESYSTEM_LIBS) $(BOOST_SYSTEM_LIBS) $(GEOIP_LIBS) $(MMDB_LIBS) diff --git a/configure.ac b/configure.ac index e3b9a048..d72912c0 100644 --- a/configure.ac +++ b/configure.ac @@ -3,6 +3,11 @@ AM_INIT_AUTOMAKE([foreign dist-bzip2 parallel-tests 1.11 subdir-objects]) AM_SILENT_RULES([yes]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_HEADERS([config.h]) + +AC_CANONICAL_HOST +: ${CFLAGS="-Wall -g -O3"} +: ${CXXFLAGS="-Wall -g -O3"} + AC_PROG_CC AC_PROG_CXX AC_LANG([C++]) @@ -49,6 +54,7 @@ BOOST_FILESYSTEM AS_IF([test -z "$BOOST_FILESYSTEM_LIBS"], [ AC_MSG_ERROR([Boost filesystem library is not installed])]) AM_CONDITIONAL([HAVE_BOOST_GE_148], [test "$boost_major_version" -ge 148]) PDNS_ENABLE_UNIT_TESTS +PDNS_ENABLE_SANITIZERS # Check for dependent programs AC_CHECK_PROG(PERL, perl, perl) AC_CHECK_PROG(HAVE_WGET, wget, wget) diff --git a/m4/pdns_enable_sanitizers.m4 b/m4/pdns_enable_sanitizers.m4 new file mode 100644 index 00000000..6773e1a9 --- /dev/null +++ b/m4/pdns_enable_sanitizers.m4 @@ -0,0 +1,167 @@ +AC_DEFUN([PDNS_ENABLE_SANITIZERS], [ + PDNS_ENABLE_ASAN + PDNS_ENABLE_MSAN + PDNS_ENABLE_TSAN + PDNS_ENABLE_LSAN + PDNS_ENABLE_UBSAN + + AS_IF([test "x$enable_asan" != "xno" -a "x$enable_tsan" != "xno"],[ + AC_MSG_ERROR([Address Sanitizer is not compatible with Thread Sanitizer]) + ]) + + AS_IF([test "x$enable_msan" != "xno" -a "x$enable_asan" != "xno"],[ + AC_MSG_ERROR([Memory Sanitizer is not compatible with Address Sanitizer]) + ]) + + AS_IF([test "x$enable_msan" != "xno" -a "x$enable_lsan" != "xno"],[ + AC_MSG_ERROR([Memory Sanitizer is not compatible with Leak Sanitizer]) + ]) + + AS_IF([test "x$enable_msan" != "xno" -a "x$enable_tsan" != "xno"],[ + AC_MSG_ERROR([Memory Sanitizer is not compatible with Thread Sanitizer]) + ]) + + AS_IF([test "x$enable_asan" != "xno" -o "x$enable_tsan" != "xno" -o "x$enable_lsan" != "xno" -o "x$enable_ubsan" != "xno" -o "x$enable_msan" != "xno"], [ + gl_WARN_ADD([-fno-omit-frame-pointer]) + ]) +]) + +AC_DEFUN([PDNS_ENABLE_ASAN], [ + AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) + AC_MSG_CHECKING([whether to enable AddressSanitizer]) + AC_ARG_ENABLE([asan], + AS_HELP_STRING([--enable-asan], + [enable AddressSanitizer @<:@default=no@:>@]), + [enable_asan=$enableval], + [enable_asan=no] + ) + AC_MSG_RESULT([$enable_asan]) + + AS_IF([test "x$enable_asan" != "xno"], [ + gl_COMPILER_OPTION_IF([-fsanitize=address], + [ + [SANITIZER_FLAGS="-fsanitize=address $SANITIZER_FLAGS"] + AC_CHECK_HEADERS([sanitizer/common_interface_defs.h], asan_headers=yes, asan_headers=no) + AS_IF([test x"$asan_headers" = "xyes" ], + [AC_CHECK_DECL(__sanitizer_start_switch_fiber, + [ + AC_MSG_CHECKING([for the exact signature of __sanitizer_finish_switch_fiber]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [#include ], + [ + __sanitizer_finish_switch_fiber(nullptr); + ]) + ], [ + AC_MSG_RESULT([a single pointer]) + AC_DEFINE([HAVE_FIBER_SANITIZER], [1], [Define if ASAN fiber annotation interface is available.]) + AC_DEFINE(HAVE_SANITIZER_FINISH_SWITCH_FIBER_SINGLE_PTR, [1], [Define to 1 if __sanitizer_finish_switch_fiber takes only a pointer]) + ], [ + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [#include ], + [ + __sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr); + ]) + ], [ + AC_MSG_RESULT([three pointers]) + AC_DEFINE([HAVE_FIBER_SANITIZER], [1], [Define if ASAN fiber annotation interface is available.]) + AC_DEFINE(HAVE_SANITIZER_FINISH_SWITCH_FIBER_THREE_PTRS, [1], [Define to 1 if __sanitizer_finish_switch_fiber takes three pointers]) + ], [ + AC_MSG_RESULT([unknown]) + AC_MSG_NOTICE([ASAN fiber switching is not available due to an unknown API version]) + ]) + ]) + ], [ + AC_MSG_NOTICE([ASAN fiber switching is not available]) + ], + [#include ] + )] + ) + ], + [AC_MSG_ERROR([Cannot enable AddressSanitizer])] + ) + ]) + AC_SUBST([SANITIZER_FLAGS]) +]) + +AC_DEFUN([PDNS_ENABLE_TSAN], [ + AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) + AC_MSG_CHECKING([whether to enable ThreadSanitizer]) + AC_ARG_ENABLE([tsan], + AS_HELP_STRING([--enable-tsan], + [enable ThreadSanitizer @<:@default=no@:>@]), + [enable_tsan=$enableval], + [enable_tsan=no] + ) + AC_MSG_RESULT([$enable_tsan]) + + AS_IF([test "x$enable_tsan" != "xno"], [ + gl_COMPILER_OPTION_IF([-fsanitize=thread], + [SANITIZER_FLAGS="-fsanitize=thread $SANITIZER_FLAGS"], + [AC_MSG_ERROR([Cannot enable ThreadSanitizer])] + ) + ]) + AC_SUBST([SANITIZER_FLAGS]) +]) + +AC_DEFUN([PDNS_ENABLE_LSAN], [ + AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) + AC_MSG_CHECKING([whether to enable LeakSanitizer]) + AC_ARG_ENABLE([lsan], + AS_HELP_STRING([--enable-lsan], + [enable LeakSanitizer @<:@default=no@:>@]), + [enable_lsan=$enableval], + [enable_lsan=no] + ) + AC_MSG_RESULT([$enable_lsan]) + + AS_IF([test "x$enable_lsan" != "xno"], [ + gl_COMPILER_OPTION_IF([-fsanitize=leak], + [SANITIZER_FLAGS="-fsanitize=leak $SANITIZER_FLAGS"], + [AC_MSG_ERROR([Cannot enable LeakSanitizer])] + ) + ]) + AC_SUBST([SANITIZER_FLAGS]) +]) + +AC_DEFUN([PDNS_ENABLE_UBSAN], [ + AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) + AC_MSG_CHECKING([whether to enable Undefined Behaviour Sanitizer]) + AC_ARG_ENABLE([ubsan], + AS_HELP_STRING([--enable-ubsan], + [enable Undefined Behaviour Sanitizer @<:@default=no@:>@]), + [enable_ubsan=$enableval], + [enable_ubsan=no] + ) + AC_MSG_RESULT([$enable_ubsan]) + + AS_IF([test "x$enable_ubsan" != "xno"], [ + gl_COMPILER_OPTION_IF([-fsanitize=undefined], + [SANITIZER_FLAGS="-fsanitize=undefined $SANITIZER_FLAGS"], + [AC_MSG_ERROR([Cannot enable Undefined Behaviour Sanitizer])] + ) + ]) + AC_SUBST([SANITIZER_FLAGS]) +]) + +AC_DEFUN([PDNS_ENABLE_MSAN], [ + AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) + AC_MSG_CHECKING([whether to enable MemorySanitizer]) + AC_ARG_ENABLE([msan], + AS_HELP_STRING([--enable-msan], + [enable MemorySanitizer @<:@default=no@:>@]), + [enable_msan=$enableval], + [enable_msan=no] + ) + AC_MSG_RESULT([$enable_msan]) + + AS_IF([test "x$enable_msan" != "xno"], [ + gl_COMPILER_OPTION_IF([-fsanitize=memory], + [SANITIZER_FLAGS="-fsanitize=memory $SANITIZER_FLAGS"], + [AC_MSG_ERROR([Cannot enable MemorySanitizer])] + ) + ]) + AC_SUBST([SANITIZER_FLAGS]) +]) + diff --git a/m4/warnings.m4 b/m4/warnings.m4 new file mode 100644 index 00000000..5ae01def --- /dev/null +++ b/m4/warnings.m4 @@ -0,0 +1,79 @@ +# warnings.m4 serial 11 +dnl Copyright (C) 2008-2015 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Simon Josefsson + +# gl_AS_VAR_APPEND(VAR, VALUE) +# ---------------------------- +# Provide the functionality of AS_VAR_APPEND if Autoconf does not have it. +m4_ifdef([AS_VAR_APPEND], +[m4_copy([AS_VAR_APPEND], [gl_AS_VAR_APPEND])], +[m4_define([gl_AS_VAR_APPEND], +[AS_VAR_SET([$1], [AS_VAR_GET([$1])$2])])]) + + +# gl_COMPILER_OPTION_IF(OPTION, [IF-SUPPORTED], [IF-NOT-SUPPORTED], +# [PROGRAM = AC_LANG_PROGRAM()]) +# ----------------------------------------------------------------- +# Check if the compiler supports OPTION when compiling PROGRAM. +# +# FIXME: gl_Warn must be used unquoted until we can assume Autoconf +# 2.64 or newer. +AC_DEFUN([gl_COMPILER_OPTION_IF], +[AS_VAR_PUSHDEF([gl_Warn], [gl_cv_warn_[]_AC_LANG_ABBREV[]_$1])dnl +AS_VAR_PUSHDEF([gl_Flags], [_AC_LANG_PREFIX[]FLAGS])dnl +AS_LITERAL_IF([$1], + [m4_pushdef([gl_Positive], m4_bpatsubst([$1], [^-Wno-], [-W]))], + [gl_positive="$1" +case $gl_positive in + -Wno-*) gl_positive=-W`expr "X$gl_positive" : 'X-Wno-\(.*\)'` ;; +esac +m4_pushdef([gl_Positive], [$gl_positive])])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler handles $1], m4_defn([gl_Warn]), [ + gl_save_compiler_FLAGS="$gl_Flags" + gl_AS_VAR_APPEND(m4_defn([gl_Flags]), + [" $gl_unknown_warnings_are_errors ]m4_defn([gl_Positive])["]) + AC_LINK_IFELSE([m4_default([$4], [AC_LANG_PROGRAM([])])], + [AS_VAR_SET(gl_Warn, [yes])], + [AS_VAR_SET(gl_Warn, [no])]) + gl_Flags="$gl_save_compiler_FLAGS" +]) +AS_VAR_IF(gl_Warn, [yes], [$2], [$3]) +m4_popdef([gl_Positive])dnl +AS_VAR_POPDEF([gl_Flags])dnl +AS_VAR_POPDEF([gl_Warn])dnl +]) + +# gl_UNKNOWN_WARNINGS_ARE_ERRORS +# ------------------------------ +# Clang doesn't complain about unknown warning options unless one also +# specifies -Wunknown-warning-option -Werror. Detect this. +AC_DEFUN([gl_UNKNOWN_WARNINGS_ARE_ERRORS], +[gl_COMPILER_OPTION_IF([-Werror -Wunknown-warning-option], + [gl_unknown_warnings_are_errors='-Wunknown-warning-option -Werror'], + [gl_unknown_warnings_are_errors=])]) + +# gl_WARN_ADD(OPTION, [VARIABLE = WARN_CFLAGS], +# [PROGRAM = AC_LANG_PROGRAM()]) +# --------------------------------------------- +# Adds parameter to WARN_CFLAGS if the compiler supports it when +# compiling PROGRAM. For example, gl_WARN_ADD([-Wparentheses]). +# +# If VARIABLE is a variable name, AC_SUBST it. +AC_DEFUN([gl_WARN_ADD], +[AC_REQUIRE([gl_UNKNOWN_WARNINGS_ARE_ERRORS]) +gl_COMPILER_OPTION_IF([$1], + [gl_AS_VAR_APPEND(m4_if([$2], [], [[WARN_CFLAGS]], [[$2]]), [" $1"])], + [], + [$3]) +m4_ifval([$2], + [AS_LITERAL_IF([$2], [AC_SUBST([$2])])], + [AC_SUBST([WARN_CFLAGS])])dnl +]) + +# Local Variables: +# mode: autoconf +# End: diff --git a/trackalert/Makefile.am b/trackalert/Makefile.am index a74006b4..b95644c8 100644 --- a/trackalert/Makefile.am +++ b/trackalert/Makefile.am @@ -1,4 +1,20 @@ -AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(EXT_CFLAGS) $(WFORCE_CFLAGS) $(libsodium_CFLAGS) $(JSON11_CFLAGS) $(LIBCURL_CFLAGS) $(LIBCRYPTO_INCLUDES) $(YAMLCPP_FLAGS) $(MMDB_CFLAGS) -O3 -Wall -pthread -DSYSCONFDIR='"$(sysconfdir)"' -I$(top_srcdir)/wforce +AM_CPPFLAGS = $(LUA_CFLAGS) \ + $(YAHTTP_CFLAGS) \ + $(EXT_CFLAGS) \ + $(WFORCE_CFLAGS) \ + $(libsodium_CFLAGS) \ + $(JSON11_CFLAGS) \ + $(LIBCURL_CFLAGS) \ + $(LIBCRYPTO_INCLUDES) \ + $(YAMLCPP_FLAGS) \ + $(MMDB_CFLAGS) \ + -pthread \ + -DSYSCONFDIR='"$(sysconfdir)"' \ + -I$(top_srcdir)/wforce + +AM_LDFLAGS = \ + $(PROGRAM_LDFLAGS) \ + $(SANITIZER_FLAGS) EXTRA_DIST= trackalert.conf README.md trackalert.service.in diff --git a/wforce/Makefile.am b/wforce/Makefile.am index d4425126..e99d02cf 100644 --- a/wforce/Makefile.am +++ b/wforce/Makefile.am @@ -1,8 +1,25 @@ -AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(WFORCE_CFLAGS) $(EXT_CFLAGS) $(libsodium_CFLAGS) $(GETDNS_CFLAGS) $(JSON11_CFLAGS) $(LIBHIREDIS_CFLAGS) $(LIBCURL_CFLAGS) $(LIBCRYPTO_INCLUDES) $(YAMLCPP_FLAGS) $(MMDB_CFLAGS) -O3 -Wall -DSYSCONFDIR='"$(sysconfdir)"' +AM_CPPFLAGS = \ + $(LUA_CFLAGS) \ + $(YAHTTP_CFLAGS) \ + $(WFORCE_CFLAGS) \ + $(EXT_CFLAGS) \ + $(libsodium_CFLAGS) \ + $(GETDNS_CFLAGS) \ + $(JSON11_CFLAGS) \ + $(LIBHIREDIS_CFLAGS) \ + $(LIBCURL_CFLAGS) \ + $(LIBCRYPTO_INCLUDES) \ + $(YAMLCPP_FLAGS) \ + $(MMDB_CFLAGS) \ + -DSYSCONFDIR='"$(sysconfdir)"' \ + $(SANITIZER_FLAGS) + +AM_LDFLAGS = \ + $(PROGRAM_LDFLAGS) \ + $(SANITIZER_FLAGS) UAP_REGEX_FILE=regexes.yaml - EXTRA_DIST= wforce.conf wforce.service.in wforce.conf.example replication.proto $(UAP_REGEX_FILE) CLEANFILES = replication.pb.cc replication.pb.h wforce.service $(UAP_REGEX_FILE)