Hi,
as described in PR, when using both ASan and UBSan (-fsanitize=address,undefined ), we have symbols collision for global functions, like __sanitizer_set_report_path. This leads to fuzzy results when printing reports into files e.g. for this test case: #include <sanitizer/common_interface_defs.h> int main(int argc, char **argv) { __sanitizer_set_report_path("/tmp/sanitizer.txt"); int i = 23; i <<= 32; int *array = new int[100]; delete [] array; return array[argc]; } only ASan's report gets written to file; UBSan output goes to stderr. To resolve this issue we could use two approaches: 1) Use the same approach to that is implemented in Clang (UBSan embedded to ASan). The only caveat here is that we need to link (unused) C++ part of UBSan even in C programs when linking static ASan runtime. This happens because GCC, as opposed to Clang, doesn't split C and C++ runtimes for sanitizers. 2) Just add SANITIZER_INTERFACE_ATTRIBUTE to report_file global variable. In this case all __sanitizer_set_report_path calls will set the same report_file variable. IMHO this is a hacky way to fix the issue, it's better to use the first option if possible. The attached patch fixes the symbols collision by embedding UBSan into ASan (variant 1), just like we do for LSan. Regtested/bootstrapped on x86_64-unknown-linux-gnu, looks reasonable enough for trunk? -Maxim
gcc/ChangeLog: 2018-05-23 Maxim Ostapenko <m.ostape...@samsung.com> * config/gnu-user.h (LIBASAN_EARLY_SPEC): Pass -lstdc++ for static libasan. * gcc.c: Do not pass LIBUBSAN_SPEC if ASan is enabled with UBSan. libsanitizer/ChangeLog: 2018-05-23 Maxim Ostapenko <m.ostape...@samsung.com> * Makefile.am: Reorder libs. * Makefile.in: Regenerate. * asan/Makefile.am: Define DCAN_SANITIZE_UB=1, add dependancy from libsanitizer_ubsan.la. * asan/Makefile.in: Regenerate. * ubsan/Makefile.am: Define new libsanitizer_ubsan.la library. * ubsan/Makefile.in: Regenerate. diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h index cba3c0b..ccae957 100644 --- a/gcc/config/gnu-user.h +++ b/gcc/config/gnu-user.h @@ -161,7 +161,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \ "%{static-libasan:%{!shared:" \ LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \ - LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}" + LD_DYNAMIC_OPTION " -lstdc++ }}%{!static-libasan:-lasan}" #undef LIBTSAN_EARLY_SPEC #define LIBTSAN_EARLY_SPEC "%{!shared:libtsan_preinit%O%s} " \ "%{static-libtsan:%{!shared:" \ diff --git a/gcc/gcc.c b/gcc/gcc.c index a716f70..215e7a0 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -984,7 +984,7 @@ proper position among the other output files. */ %{static:%ecannot specify -static with -fsanitize=address}}\ %{%:sanitize(thread):" LIBTSAN_SPEC "\ %{static:%ecannot specify -static with -fsanitize=thread}}\ - %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\ + %{!%:sanitize(address):%{%:sanitize(undefined):" LIBUBSAN_SPEC "}}\ %{%:sanitize(leak):" LIBLSAN_SPEC "}}}" #endif diff --git a/libsanitizer/Makefile.am b/libsanitizer/Makefile.am index 018f0b0..08d952b 100644 --- a/libsanitizer/Makefile.am +++ b/libsanitizer/Makefile.am @@ -14,7 +14,7 @@ endif if LIBBACKTRACE_SUPPORTED SUBDIRS += libbacktrace endif -SUBDIRS += lsan asan ubsan +SUBDIRS += lsan ubsan asan nodist_saninclude_HEADERS += \ include/sanitizer/lsan_interface.h \ include/sanitizer/asan_interface.h \ diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in index a9fea21e..9074292 100644 --- a/libsanitizer/Makefile.in +++ b/libsanitizer/Makefile.in @@ -140,8 +140,8 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS ETAGS = etags CTAGS = ctags -DIST_SUBDIRS = sanitizer_common interception libbacktrace lsan asan \ - ubsan tsan +DIST_SUBDIRS = sanitizer_common interception libbacktrace lsan ubsan \ + asan tsan ACLOCAL = @ACLOCAL@ ALLOC_FILE = @ALLOC_FILE@ AMTAR = @AMTAR@ @@ -294,7 +294,7 @@ ACLOCAL_AMFLAGS = -I .. -I ../config sanincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/sanitizer nodist_saninclude_HEADERS = $(am__append_1) @SANITIZER_SUPPORTED_TRUE@SUBDIRS = sanitizer_common $(am__append_2) \ -@SANITIZER_SUPPORTED_TRUE@ $(am__append_3) lsan asan ubsan \ +@SANITIZER_SUPPORTED_TRUE@ $(am__append_3) lsan ubsan asan \ @SANITIZER_SUPPORTED_TRUE@ $(am__append_4) gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am index f105b03..3ac49ee 100644 --- a/libsanitizer/asan/Makefile.am +++ b/libsanitizer/asan/Makefile.am @@ -3,7 +3,7 @@ AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir) # May be used by toolexeclibdir. gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER) -DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 -DCAN_SANITIZE_UB=0 +DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 -DCAN_SANITIZE_UB=1 if USING_MAC_INTERPOSE DEFS += -DMAC_INTERPOSE_FUNCTIONS -DMISSING_BLOCKS_SUPPORT endif @@ -48,7 +48,7 @@ asan_files = \ asan_win_dynamic_runtime_thunk.cc libasan_la_SOURCES = $(asan_files) -libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/lsan/libsanitizer_lsan.la +libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/lsan/libsanitizer_lsan.la $(top_builddir)/ubsan/libsanitizer_ubsan.la if !USING_MAC_INTERPOSE libasan_la_LIBADD += $(top_builddir)/interception/libinterception.la endif diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in index 4cf27e7..8ce2362 100644 --- a/libsanitizer/asan/Makefile.in +++ b/libsanitizer/asan/Makefile.in @@ -110,7 +110,8 @@ LTLIBRARIES = $(toolexeclib_LTLIBRARIES) am__DEPENDENCIES_1 = libasan_la_DEPENDENCIES = \ $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(top_builddir)/lsan/libsanitizer_lsan.la $(am__append_2) \ + $(top_builddir)/lsan/libsanitizer_lsan.la \ + $(top_builddir)/ubsan/libsanitizer_ubsan.la $(am__append_2) \ $(am__append_3) $(am__DEPENDENCIES_1) am__objects_1 = asan_activation.lo asan_allocator.lo asan_debugging.lo \ asan_descriptions.lo asan_errors.lo asan_fake_stack.lo \ @@ -176,7 +177,7 @@ CYGPATH_W = @CYGPATH_W@ DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS \ -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \ -DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 \ - -DCAN_SANITIZE_UB=0 $(am__append_1) + -DCAN_SANITIZE_UB=1 $(am__append_1) DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ @@ -346,7 +347,8 @@ asan_files = \ libasan_la_SOURCES = $(asan_files) libasan_la_LIBADD = \ $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(top_builddir)/lsan/libsanitizer_lsan.la $(am__append_2) \ + $(top_builddir)/lsan/libsanitizer_lsan.la \ + $(top_builddir)/ubsan/libsanitizer_ubsan.la $(am__append_2) \ $(am__append_3) $(LIBSTDCXX_RAW_CXX_LDFLAGS) libasan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(link_libasan) diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am index 2bff6be..1bb40bd 100644 --- a/libsanitizer/ubsan/Makefile.am +++ b/libsanitizer/ubsan/Makefile.am @@ -11,6 +11,7 @@ AM_CXXFLAGS += $(EXTRA_CXXFLAGS) ACLOCAL_AMFLAGS = -I m4 toolexeclib_LTLIBRARIES = libubsan.la +noinst_LTLIBRARIES = libsanitizer_ubsan.la ubsan_plugin_files = \ ubsan_diag.cc \ @@ -25,7 +26,10 @@ ubsan_plugin_files = \ ubsan_files = $(ubsan_plugin_files) -libubsan_la_SOURCES = $(ubsan_files) +libsanitizer_ubsan_la_SOURCES = $(ubsan_plugin_files) +libsanitizer_ubsan_la_LIBADD = $(LIBSTDCXX_RAW_CXX_LDFLAGS) + +libubsan_la_SOURCES = $(ubsan_files) libubsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la if !USING_MAC_INTERPOSE libubsan_la_LIBADD += $(top_builddir)/interception/libinterception.la diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in index d75260f..2102def 100644 --- a/libsanitizer/ubsan/Makefile.in +++ b/libsanitizer/ubsan/Makefile.in @@ -103,15 +103,18 @@ am__uninstall_files_from_dir = { \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(toolexeclibdir)" -LTLIBRARIES = $(toolexeclib_LTLIBRARIES) +LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES) am__DEPENDENCIES_1 = -libubsan_la_DEPENDENCIES = \ - $(top_builddir)/sanitizer_common/libsanitizer_common.la \ - $(am__append_1) $(am__append_2) $(am__DEPENDENCIES_1) +libsanitizer_ubsan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) am__objects_1 = ubsan_diag.lo ubsan_flags.lo ubsan_handlers.lo \ ubsan_handlers_cxx.lo ubsan_init.lo ubsan_type_hash.lo \ ubsan_type_hash_itanium.lo ubsan_type_hash_win.lo \ ubsan_value.lo +am_libsanitizer_ubsan_la_OBJECTS = $(am__objects_1) +libsanitizer_ubsan_la_OBJECTS = $(am_libsanitizer_ubsan_la_OBJECTS) +libubsan_la_DEPENDENCIES = \ + $(top_builddir)/sanitizer_common/libsanitizer_common.la \ + $(am__append_1) $(am__append_2) $(am__DEPENDENCIES_1) am__objects_2 = $(am__objects_1) am_libubsan_la_OBJECTS = $(am__objects_2) libubsan_la_OBJECTS = $(am_libubsan_la_OBJECTS) @@ -131,7 +134,7 @@ CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(libubsan_la_SOURCES) +SOURCES = $(libsanitizer_ubsan_la_SOURCES) $(libubsan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -298,6 +301,7 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \ -std=gnu++11 $(EXTRA_CXXFLAGS) ACLOCAL_AMFLAGS = -I m4 toolexeclib_LTLIBRARIES = libubsan.la +noinst_LTLIBRARIES = libsanitizer_ubsan.la ubsan_plugin_files = \ ubsan_diag.cc \ ubsan_flags.cc \ @@ -310,7 +314,9 @@ ubsan_plugin_files = \ ubsan_value.cc ubsan_files = $(ubsan_plugin_files) -libubsan_la_SOURCES = $(ubsan_files) +libsanitizer_ubsan_la_SOURCES = $(ubsan_plugin_files) +libsanitizer_ubsan_la_LIBADD = $(LIBSTDCXX_RAW_CXX_LDFLAGS) +libubsan_la_SOURCES = $(ubsan_files) libubsan_la_LIBADD = \ $(top_builddir)/sanitizer_common/libsanitizer_common.la \ $(am__append_1) $(am__append_2) $(LIBSTDCXX_RAW_CXX_LDFLAGS) @@ -389,6 +395,15 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \ @@ -421,6 +436,8 @@ clean-toolexeclibLTLIBRARIES: echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done +libsanitizer_ubsan.la: $(libsanitizer_ubsan_la_OBJECTS) $(libsanitizer_ubsan_la_DEPENDENCIES) $(EXTRA_libsanitizer_ubsan_la_DEPENDENCIES) + $(CXXLINK) $(libsanitizer_ubsan_la_OBJECTS) $(libsanitizer_ubsan_la_LIBADD) $(LIBS) libubsan.la: $(libubsan_la_OBJECTS) $(libubsan_la_DEPENDENCIES) $(EXTRA_libubsan_la_DEPENDENCIES) $(libubsan_la_LINK) -rpath $(toolexeclibdir) $(libubsan_la_OBJECTS) $(libubsan_la_LIBADD) $(LIBS) @@ -557,8 +574,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + clean-toolexeclibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -629,18 +646,19 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-toolexeclibLTLIBRARIES ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags dvi dvi-am html html-am info info-am install \ - install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am install-man \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip install-toolexeclibLTLIBRARIES installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-toolexeclibLTLIBRARIES + clean-libtool clean-noinstLTLIBRARIES \ + clean-toolexeclibLTLIBRARIES ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip \ + install-toolexeclibLTLIBRARIES installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-toolexeclibLTLIBRARIES # Use special rules for files that require RTTI support.