diff --git a/site_scons/site_tools/compiler_setup.py b/site_scons/site_tools/compiler_setup.py index ec4994c7ea5..19cbda2481e 100644 --- a/site_scons/site_tools/compiler_setup.py +++ b/site_scons/site_tools/compiler_setup.py @@ -82,8 +82,14 @@ def _base_setup(env): '-Wno-stringop-truncation'] asan_flags = [] + san_libs = [] + # Sanitizer runtime libraries that must be linked explicitly. + # GCC injects them for pure-C targets but CGO bypasses that path. + _sanitizer_libs = {'undefined': '-lubsan', 'thread': '-ltsan'} for sanitizer in env['SANITIZERS'].split(','): asan_flags.append(f"-fsanitize={sanitizer}") + if sanitizer in _sanitizer_libs: + san_libs.append(_sanitizer_libs[sanitizer]) env.AppendIfSupported(CCFLAGS=cc_flags + asan_flags) @@ -92,6 +98,14 @@ def _base_setup(env): env.AppendUnique(LINKFLAGS=flag) print(f"Enabling {flag.split('=')[1]} sanitizer for C code") + for lib in san_libs: + env.AppendUnique(LINKFLAGS=lib) + # Also inject into CGO_LDFLAGS so that 'go build' (which invokes + # the C linker via CGO) includes the sanitizer runtime libraries. + # Without this, any Go binary that CGO-links a UBSan-compiled C + # archive gets "DSO missing from command line" for libubsan.so.1. + env.AppendENVPath('CGO_LDFLAGS', lib, sep=' ') + if env.get('HEAP_PROFILER'): env.AppendUnique(LINKFLAGS="-ltcmalloc") print("Enabling Gperftools Heap Profiler") @@ -116,10 +130,8 @@ def _base_setup(env): env.AppendUnique(CPPDEFINES={'FAULT_INJECTION': '1'}) env.AppendUnique(CPPDEFINES={'BUILD_PIPELINE': '1'}) - if env['CMOCKA_FILTER_SUPPORTED']: - env.AppendUnique(CPPDEFINES={'CMOCKA_FILTER_SUPPORTED': '1'}) - else: - env.AppendUnique(CPPDEFINES={'CMOCKA_FILTER_SUPPORTED': '0'}) + cmocka_val = '1' if env['CMOCKA_FILTER_SUPPORTED'] else '0' + env.AppendUnique(CPPDEFINES={'CMOCKA_FILTER_SUPPORTED': cmocka_val}) env.AppendUnique(CPPDEFINES='_GNU_SOURCE') diff --git a/src/control/SConscript b/src/control/SConscript index 3af67828687..7b0d230cf8a 100644 --- a/src/control/SConscript +++ b/src/control/SConscript @@ -127,7 +127,7 @@ def install_go_bin(env, name, libs=None, install_man=False): + f'{get_build_tags(env)} ' + f'-o {build_bin} {install_src}') env.Install('$PREFIX/bin', target) - if install_man: + if install_man and not env.get('SANITIZERS'): gen_bin = join('$BUILD_DIR/src/control', name) build_path = join('$BUILD_DIR/src/control', f'{name}.8') menv = env.Clone() diff --git a/src/gurt/misc.c b/src/gurt/misc.c index df0e6b5ecc6..73c8f554afa 100644 --- a/src/gurt/misc.c +++ b/src/gurt/misc.c @@ -112,7 +112,14 @@ d_free(void *ptr) { size_t msize = _f_get_alloc_size(ptr); + /* Skip poisoning under TSan: it turns harmless zero-size-allocation + * address reuse into a false heap-use-after-free (DAOS-18626 TSAN-02/03). + */ +#if !defined(__SANITIZE_THREAD__) memset(ptr, 0x42, msize); +#else + (void)msize; +#endif free(ptr); } diff --git a/utils/cq/words.dict b/utils/cq/words.dict index 562e6ea1822..150411a2846 100644 --- a/utils/cq/words.dict +++ b/utils/cq/words.dict @@ -11,6 +11,7 @@ CompletedProcess DArray DDict DFS +DSO DataLoader Datamover EL @@ -58,8 +59,10 @@ SX Skylake SubProcess Subdirectories +TSan TestFail Testcase +UBSan UCX UNS Uncomment diff --git a/utils/docker/Dockerfile.el.9 b/utils/docker/Dockerfile.el.9 index fcdd0fc9d17..74bc5b70fc0 100644 --- a/utils/docker/Dockerfile.el.9 +++ b/utils/docker/Dockerfile.el.9 @@ -165,15 +165,17 @@ COPY --chown=daos_server:daos_server utils/completion utils/completion # select compiler to use ARG COMPILER=gcc +ARG SANITIZERS ARG JOBS=$DEPS_JOBS ARG DAOS_BUILD_TYPE=$DAOS_TARGET_TYPE ARG DAOS_BUILD=$DAOS_DEPS_BUILD # Build DAOS RUN [ "$DAOS_BUILD" != "yes" ] || { \ - scons --jobs $JOBS install PREFIX=/opt/daos COMPILER=$COMPILER \ - FIRMWARE_MGMT=1 BUILD_TYPE=$DAOS_BUILD_TYPE \ - TARGET_TYPE=$DAOS_TARGET_TYPE && \ + scons --jobs $JOBS install PREFIX=/opt/daos COMPILER=$COMPILER \ + ${SANITIZERS:+SANITIZERS=$SANITIZERS} FIRMWARE_MGMT=1 \ + BUILD_TYPE=$DAOS_BUILD_TYPE TARGET_TYPE=$DAOS_TARGET_TYPE \ + && \ ([ "$DAOS_KEEP_BUILD" != "no" ] || /bin/rm -rf build) && \ go clean -cache && \ cp -r utils/config/examples /opt/daos; \ diff --git a/utils/scripts/install-el9.sh b/utils/scripts/install-el9.sh index 8f32803071c..47250b2f244 100755 --- a/utils/scripts/install-el9.sh +++ b/utils/scripts/install-el9.sh @@ -23,6 +23,7 @@ dnf --nodocs install ${dnf_install_args} \ clang \ clang-tools-extra \ cmake \ + compiler-rt \ createrepo \ CUnit-devel \ daxctl-devel \ @@ -47,6 +48,8 @@ dnf --nodocs install ${dnf_install_args} \ json-c-devel \ libaio-devel \ libasan \ + libubsan \ + libtsan \ libcmocka-devel \ libevent-devel \ libipmctl-devel \