diff --git a/Cargo.toml b/Cargo.toml index 615508c3..e1f992b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -87,5 +87,7 @@ lto = true [features] sqlite-rpmdb-default = [] fedora-integration = [] +# ASAN+UBSAN +sanitizers = [] default = [] diff --git a/Makefile-rpm-ostree.am b/Makefile-rpm-ostree.am index aad4b2da..09889a91 100644 --- a/Makefile-rpm-ostree.am +++ b/Makefile-rpm-ostree.am @@ -88,7 +88,9 @@ rpmostree_common_libs = libglnx.la librpmostreecxxrs.la rpmostree_bin_common_libs = librpmostreeinternals.la $(rpmostree_common_libs) librpmostreeinternals_la_CFLAGS = $(AM_CFLAGS) $(rpmostree_common_cflags) -librpmostreeinternals_la_CXXFLAGS = $(AM_CXXFLAGS) $(rpmostree_common_cflags) +# Note for now we only inject the sanitizer flags into our static library, +# because doing ASAN for a shared library is trickier. +librpmostreeinternals_la_CXXFLAGS = $(AM_CXXFLAGS) $(sanitizer_flags) $(rpmostree_common_cflags) librpmostreeinternals_la_LIBADD = $(rpmostree_common_libs) privdatadir=$(pkglibdir) @@ -103,6 +105,9 @@ endif if BUILDOPT_ENABLE_SQLITE_RPMDB_DEFAULT cargo_build += --features sqlite-rpmdb-default endif +if BUILDOPT_ASAN +cargo_build += --features sanitizers +endif if RUST_DEBUG cargo_target_dir=debug @@ -138,7 +143,7 @@ endif noinst_LTLIBRARIES += librpmostreecxxrs.la librpmostreecxxrs_la_SOURCES = rpmostree-cxxrs.h rpmostree-cxxrs.cxx # Suppress missing-declarations because https://github.com/dtolnay/cxx/issues/590 -librpmostreecxxrs_la_CXXFLAGS = $(AM_CXXFLAGS) $(rpmostree_common_cflags) -Wno-missing-declarations +librpmostreecxxrs_la_CXXFLAGS = $(AM_CXXFLAGS) $(SANITIZER_FLAGS) $(rpmostree_common_cflags) -Wno-missing-declarations librpmostreecxxrs_la_LIBADD = -lstdc++ GITIGNOREFILES += $(binding_generated_sources) BUILT_SOURCES += $(binding_generated_sources) diff --git a/Makefile.am b/Makefile.am index 7626987d..ac204677 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,10 +54,14 @@ endif warnings_error_only_c = strict-prototypes missing-prototypes \ implicit-function-declaration int-conversion incompatible-pointer-types \ $(NULL) +sanitizer_flags = +if BUILDOPT_ASAN +sanitizer_flags += -fsanitize=address -fsanitize=undefined -fsanitize-undefined-trap-on-error +endif # See the AM_CFLAGS in libostree for more information about -fno-strict-aliasing AM_CFLAGS += -std=gnu11 -fno-strict-aliasing $(warning_flags) $(patsubst %,-Werror=%,$(warnings_error_only_c)) # Our default CXX flags -AM_CXXFLAGS += -std=c++17 -fno-strict-aliasing $(warning_flags) +AM_CXXFLAGS += -std=c++17 -fno-strict-aliasing $(warning_flags) $(sanitizer_flags) EXTRA_DIST += autogen.sh COPYING diff --git a/build.rs b/build.rs index f3f11c0d..762a3b6b 100644 --- a/build.rs +++ b/build.rs @@ -16,6 +16,11 @@ fn detect_fedora_feature() -> Result<()> { } fn main() -> Result<()> { + if std::env::var("CARGO_FEATURE_SANITIZERS").is_ok() { + // Force these on + println!("cargo:rustc-link-lib=ubsan"); + println!("cargo:rustc-link-lib=asan"); + } let cwd = std::env::current_dir()?; let cwd = cwd.to_str().expect("utf8 pwd"); println!("cargo:rustc-link-search={}/.libs", cwd); diff --git a/configure.ac b/configure.ac index 26651f60..66f12c85 100644 --- a/configure.ac +++ b/configure.ac @@ -27,14 +27,11 @@ dnl if not set, which we definitely want; cmake doesn't do that. AC_PROG_CXX AM_PROG_CC_C_O -AC_MSG_CHECKING([for -fsanitize=address in CFLAGS]) -if echo $CFLAGS | grep -q -e -fsanitize=address; then -AC_MSG_RESULT([yes]) -using_asan=yes -else -AC_MSG_RESULT([no]) -fi -AM_CONDITIONAL(BUILDOPT_ASAN, [test x$using_asan = xyes]) +AC_ARG_ENABLE(sanitizers, + AS_HELP_STRING([--enable-sanitizers], + [Enable ASAN and UBSAN (default: no)]),, + [enable_sanitizers=no]) +AM_CONDITIONAL(BUILDOPT_ASAN, [test x$enable_sanitizers != xno]) # Initialize libtool LT_PREREQ([2.2.4]) @@ -150,6 +147,7 @@ echo " introspection: $found_introspection rojig: ${enable_rojig:-no} + ASAN + UBSAN: ${enable_sanitizers:-no} gtk-doc: $enable_gtk_doc rust: $rust_debug_release cbindgen: ${cbindgen:-external} diff --git a/packaging/rpm-ostree.spec.in b/packaging/rpm-ostree.spec.in index 0ea647bc..8240456d 100644 --- a/packaging/rpm-ostree.spec.in +++ b/packaging/rpm-ostree.spec.in @@ -22,6 +22,9 @@ BuildRequires: cargo BuildRequires: rust %endif +# Enable ASAN + UBSAN +%bcond_with sanitizers + # RHEL8 doesn't ship zchunk today. See also the comments # in configure.ac around this as libdnf/librepo need to be in # sync, and today we bundle libdnf but not librepo. @@ -131,7 +134,8 @@ env NOCONFIGURE=1 ./autogen.sh # the %%configure macro today assumes (reasonably) that one is building # C/C++ and sets C{,XX}FLAGS export RUSTFLAGS="%{build_rustflags}" -%configure --disable-silent-rules --enable-gtk-doc %{?sqlite_rpmdb_default} +%configure --disable-silent-rules --enable-gtk-doc %{?sqlite_rpmdb_default} %{?with_sanitizers:--enable-sanitizers} + %make_build %install