diff --git a/.github/workflows/weekly-ci-rt-checkers.yml b/.github/workflows/weekly-ci-rt-checkers.yml index 2b538b02..05841e75 100644 --- a/.github/workflows/weekly-ci-rt-checkers.yml +++ b/.github/workflows/weekly-ci-rt-checkers.yml @@ -47,6 +47,7 @@ jobs: git clone --branch "$GITHUB_REF_NAME" --depth 1 https://github.com/upx/upx . git submodule update --init git clone --depth=1 https://github.com/upx/upx-testsuite ../upx-testsuite + - name: 'Build clang-static' run: | export CC="clang -static" CXX="clang++ -static" @@ -55,16 +56,17 @@ jobs: if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported run: | # unfortunately ASAN does not support static linking - flags="-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fno-omit-frame-pointer -D__SANITIZE_ADDRESS__=1" + flags="-fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined -fno-omit-frame-pointer" export CC="clang $flags" CXX="clang++ $flags" make UPX_XTARGET=clang-asan xtarget/$release - name: 'Build clang-msan' if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported run: | # unfortunately MSAN does not support static linking - flags="-fsanitize=memory -fsanitize=undefined -fno-omit-frame-pointer -D__SANITIZE_ADDRESS__=1 -DDOCTEST_CONFIG_DISABLE=1" + flags="-fsanitize=memory -fsanitize=undefined -fno-omit-frame-pointer -DDOCTEST_CONFIG_DISABLE=1" export CC="clang $flags" CXX="clang++ $flags" make UPX_XTARGET=clang-msan xtarget/$release + - name: 'Make artifact' run: | N=$(echo "upx-${GITHUB_REF_NAME}-${GITHUB_SHA:0:7}-weekly-ci-runtime-checkers-${{ matrix.container }}-${{ matrix.release }}" | sed 's/[^0-9a-zA-Z_.-]/-/g') @@ -79,6 +81,16 @@ jobs: with: name: ${{ env.artifact_name }} path: tmp/artifact + + - name: 'Run basic tests clang-static' + run: 'make -C build/xtarget/clang-static/$release test' + - name: 'Run basic tests clang-asan' + if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported + run: 'make -C build/xtarget/clang-asan/$release test' + - name: 'Run basic tests clang-msan' + if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: MSAN not supported + run: 'make -C build/xtarget/clang-msan/$release test' + - name: 'Run testsuite clang-asan' if: ${{ !startsWith(matrix.container, 'i386/') }} # i386: ASAN not supported run: | diff --git a/src/conf.h b/src/conf.h index 465aec9b..a4748e22 100644 --- a/src/conf.h +++ b/src/conf.h @@ -34,6 +34,16 @@ #include "headers.h" #include "version.h" +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif +#if !defined(__has_builtin) +#define __has_builtin(x) 0 +#endif +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif + // reserve name "upx" for namespace namespace upx {} @@ -319,10 +329,6 @@ inline void NO_fprintf(FILE *, const char *, ...) noexcept attribute_format(2, 3 inline void NO_printf(const char *, ...) noexcept {} inline void NO_fprintf(FILE *, const char *, ...) noexcept {} -#if !defined(__has_builtin) -# define __has_builtin(x) 0 -#endif - #if __has_builtin(__builtin_memcpy_inline) # define upx_memcpy_inline __builtin_memcpy_inline #elif __has_builtin(__builtin_memcpy) diff --git a/src/headers.h b/src/headers.h index c17529d3..5b2ddc83 100644 --- a/src/headers.h +++ b/src/headers.h @@ -109,6 +109,18 @@ static_assert(sizeof(void *) == 8); #include #endif +// sanitizers +#if !defined(__SANITIZE_ADDRESS__) && defined(__has_feature) +#if __has_feature(address_sanitizer) +#define __SANITIZE_ADDRESS__ 1 +#endif +#endif +#if !defined(__SANITIZE_MEMORY__) && defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define __SANITIZE_MEMORY__ 1 +#endif +#endif + // UPX vendor git submodule headers #include #if WITH_BOOST_PFR @@ -121,7 +133,8 @@ static_assert(sizeof(void *) == 8); #ifndef WITH_VALGRIND #define WITH_VALGRIND 1 #endif -#if defined(__SANITIZE_ADDRESS__) || defined(_WIN32) || !defined(__GNUC__) +#if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_MEMORY__) || defined(_WIN32) || \ + !defined(__GNUC__) #undef WITH_VALGRIND #endif #if WITH_VALGRIND diff --git a/src/util/membuffer.cpp b/src/util/membuffer.cpp index 50eb90bb..4cc85794 100644 --- a/src/util/membuffer.cpp +++ b/src/util/membuffer.cpp @@ -47,7 +47,7 @@ unsigned membuffer_get_size(MemBuffer &mb) noexcept { return mb.getSize(); } // bool use_simple_mcheck() **************************************************************************/ -#if defined(__SANITIZE_ADDRESS__) +#if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_MEMORY__) static forceinline constexpr bool use_simple_mcheck() noexcept { return false; } #elif (WITH_VALGRIND) && defined(RUNNING_ON_VALGRIND) static bool use_simple_mcheck_flag; @@ -190,7 +190,7 @@ void MemBuffer::alloc(upx_uint64_t bytes) { set_ne32(p + size_in_bytes + 4, stats.global_alloc_counter); } ptr = (pointer) (void *) p; -#if DEBUG +#if !defined(__SANITIZE_MEMORY__) && DEBUG memset(ptr, 0xfb, size_in_bytes); (void) VALGRIND_MAKE_MEM_UNDEFINED(ptr, size_in_bytes); #endif diff --git a/src/util/util.h b/src/util/util.h index 9c030fea..bfc7331b 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -70,12 +70,18 @@ inline void mem_size_assert(upx_uint64_t element_size, upx_uint64_t n) { #if DEBUG template T *NewArray(upx_uint64_t n) { + COMPILE_TIME_ASSERT(std::is_standard_layout::value) + COMPILE_TIME_ASSERT(std::is_trivially_copyable::value) + COMPILE_TIME_ASSERT(std::is_trivially_default_constructible::value) size_t bytes = mem_size(sizeof(T), n); // assert size T *array = new T[size_t(n)]; +#if !defined(__SANITIZE_MEMORY__) if (array != nullptr && bytes > 0) { memset(array, 0xfb, bytes); (void) VALGRIND_MAKE_MEM_UNDEFINED(array, bytes); } +#endif + UNUSED(bytes); return array; } #define New(type, n) (NewArray((n)))