diff --git a/configure.ac b/configure.ac index e56062a8f7..c8d72d3cca 100644 --- a/configure.ac +++ b/configure.ac @@ -972,6 +972,39 @@ if (test "${enable_ld_gc}" != "no"); then fi fi +AC_ARG_ENABLE(address-sanitizer, AS_HELP_STRING([--enable-address-sanitizer], + [Compile with address sanitizer (default: no)])) +if (test "${enable_address_sanitizer}" = "yes"); then + CC_CHECK_FLAGS_APPEND([asan_cflags], [CFLAGS], [-fsanitize=address]) + AS_IF([test -z "$asan_cflags"], + [AC_MSG_ERROR([*** -fsanitize=address is not supported])]) + + sanitizer_cflags="$sanitizer_cflags -fsanitize=address" + sanitizer_ldflags="$sanitizer_ldflags -Wc,-fsanitize=address" + sanitizers="${sanitizers}asan " +fi + +AC_ARG_ENABLE(undefined-sanitizer, AS_HELP_STRING([--enable-undefined-sanitizer], + [Compile with undefined behavior sanitizer (default: no)])) +if (test "${enable_undefined_sanitizer}" = "yes"); then + CC_CHECK_FLAGS_APPEND([ubsan_cflags], [CFLAGS], [-fsanitize=undefined]) + AS_IF([test -z "$ubsan_cflags"], + [AC_MSG_ERROR([*** -fsanitize=undefined is not supported])]) + + sanitizer_cflags="$sanitizer_cflags -fsanitize=undefined" + sanitizer_ldflags="$sanitizer_ldflags -Wc,-fsanitize=undefined" + sanitizers="${sanitizers}ubsan " +fi + +if test -n "$sanitizers"; then + CFLAGS="$CFLAGS $sanitizer_cflags -DVALGRIND=1 -fno-omit-frame-pointer" + LDFLAGS="$LDFLAGS $sanitizer_ldflags" + sanitizers="${sanitizers% }" + AC_SUBST(SANITIZER_ENV, [ASAN_OPTIONS=detect_leaks=0]) +fi + +AC_SUBST(SANITIZERS, [$sanitizers]) + dnl ------------------------- dnl Vala bindings dnl ------------------------- @@ -1068,7 +1101,6 @@ fi AM_CONDITIONAL(BUILD_SETTING_DOCS, test "$build_setting_docs" = "yes") AM_CONDITIONAL(SETTING_DOCS_AVAILABLE, test "$build_setting_docs" = "yes" -o "$have_setting_docs" = "yes") - AC_CONFIG_FILES([ Makefile shared/Makefile @@ -1233,4 +1265,5 @@ echo " code coverage: $enable_code_coverage" echo " LTO: $enable_lto" echo " linker garbage collection: $enable_ld_gc" echo " JSON validation: $enable_json_validation" +echo " sanitizers: $sanitizers" echo diff --git a/contrib/fedora/rpm/NetworkManager.spec b/contrib/fedora/rpm/NetworkManager.spec index 73cf3704fc..faaa2d5368 100644 --- a/contrib/fedora/rpm/NetworkManager.spec +++ b/contrib/fedora/rpm/NetworkManager.spec @@ -375,6 +375,8 @@ intltoolize --automake --copy --force %if %{with debug} --with-more-logging \ --with-more-asserts=10000 \ + --enable-address-sanitizer \ + --enable-undefined-sanitizer \ %endif --enable-ppp=yes \ --with-libaudit=yes-disabled-by-default \ diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index c406847474..6cb3e4b826 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -196,6 +196,10 @@ CLEANFILES = $(BUILT_SOURCES) INTROSPECTION_GIRS = INTROSPECTION_COMPILER_ARGS = --includedir=$(top_builddir)/libnm-util +# Pass SANITIZER_ENV where a command that uses built libraries is +# executed, to suppress possible errors +INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV) + if HAVE_INTROSPECTION introspection_sources = $(libnminclude_HEADERS) $(libnm_glib_la_csources) diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am index 8f51fc37c7..0d5a0d46c1 100644 --- a/libnm-util/Makefile.am +++ b/libnm-util/Makefile.am @@ -169,6 +169,10 @@ INTROSPECTION_GIRS = INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) +# Pass SANITIZER_ENV where a command that uses built libraries is +# executed, to suppress possible errors +INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV) + if HAVE_INTROSPECTION introspection_sources = $(libnm_util_include_HEADERS) $(nodist_libnm_util_include_HEADERS) $(libnm_util_la_csources) diff --git a/libnm/Makefile.am b/libnm/Makefile.am index e035b3cda2..e1ae02e949 100644 --- a/libnm/Makefile.am +++ b/libnm/Makefile.am @@ -141,12 +141,10 @@ libnm_la_LIBADD = \ $(UUID_LIBS) \ $(GUDEV_LIBS) -libnm_la_LDFLAGS = \ - $(CODE_COVERAGE_LDFLAGS) - SYMBOL_VIS_FILE=$(srcdir)/libnm.ver libnm_la_LDFLAGS = -Wl,--version-script=$(SYMBOL_VIS_FILE) \ + $(CODE_COVERAGE_LDFLAGS) \ -version-info "1:0:1" ### @@ -170,6 +168,10 @@ INTROSPECTION_COMPILER_ARGS = \ --includedir=$(top_srcdir)/libnm \ --includedir=$(top_builddir)/libnm +# Pass SANITIZER_ENV where a command that uses built libraries is +# executed, to suppress possible errors +INTROSPECTION_SCANNER_ENV = $(SANITIZER_ENV) + if HAVE_INTROSPECTION introspection_sources = \ $(libnm_core_headers) \ @@ -213,9 +215,16 @@ docs_sources = $(filter-out %/nm-core-enum-types.c,$(libnm_core_sources)) nm-setting-docs-overrides.xml: generate-plugin-docs.pl $(docs_sources) $(srcdir)/generate-plugin-docs.pl dbus $(top_srcdir)/libnm-core $@ +# When the python scripts loads libnm and the address sanitizers is +# enabled, we must LD_PRELOAD libasan otherwise it will complain that +# it was not loaded as initial library. nm-property-docs.xml: generate-setting-docs.py $(docs_sources) | NM-1.0.gir NM-1.0.typelib libnm.la export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ + if echo $(CFLAGS) | grep -e -fsanitize=address; then \ + export LD_PRELOAD="$${LD_PRELOAD} $$(ldd $(abs_builddir)/.libs/libnm.so | grep libasan\.so\.. -o | head -n 1)"; \ + fi; \ + [ -n "$(SANITIZER_ENV)" ] && export $(SANITIZER_ENV) ; \ $(srcdir)/generate-setting-docs.py \ --gir $(builddir)/NM-1.0.gir \ --output $@ @@ -223,6 +232,10 @@ nm-property-docs.xml: generate-setting-docs.py $(docs_sources) | NM-1.0.gir NM-1 nm-setting-docs.xml: generate-setting-docs.py $(docs_sources) nm-setting-docs-overrides.xml | NM-1.0.gir NM-1.0.typelib libnm.la export GI_TYPELIB_PATH=$(abs_builddir)$${GI_TYPELIB_PATH:+:$$GI_TYPELIB_PATH}; \ export LD_LIBRARY_PATH=$(abs_builddir)/.libs$${LD_LIBRARY_PATH:+:$$LD_LIBRARY_PATH}; \ + if echo $(CFLAGS) | grep -e -fsanitize=address; then \ + export LD_PRELOAD="$${LD_PRELOAD} $$(ldd $(abs_builddir)/.libs/libnm.so | grep libasan\.so\.. -o | head -n 1)"; \ + fi; \ + [ -n "$(SANITIZER_ENV)" ] && export $(SANITIZER_ENV) ; \ $(srcdir)/generate-setting-docs.py \ --gir $(builddir)/NM-1.0.gir \ --overrides $(builddir)/nm-setting-docs-overrides.xml \