chore: Add an undefined behaviour/integer sanitizer build.

This commit is contained in:
iphydf 2022-02-08 01:06:59 +00:00
parent 71d5f8a4c3
commit 6f36b67a13
No known key found for this signature in database
GPG Key ID: 3855DBA2D74403C9
7 changed files with 67 additions and 12 deletions

View File

@ -8,7 +8,7 @@ CACHEDIR="$HOME/cache"
add_flag -Werror
add_flag -fdiagnostics-color=always
add_flag -fno-omit-frame-pointer
add_flag -fsanitize=address,undefined
add_flag -fsanitize=address
cmake -B_build -H. -GNinja \
-DCMAKE_C_FLAGS="$C_FLAGS" \
-DCMAKE_CXX_FLAGS="$CXX_FLAGS" \
@ -28,7 +28,8 @@ cd _build
ninja install -j"$(nproc)"
export ASAN_OPTIONS="detect_invalid_pointer_pairs=1"
export ASAN_OPTIONS="color=always"
export ASAN_OPTIONS="$ASAN_OPTIONS,detect_invalid_pointer_pairs=1"
export ASAN_OPTIONS="$ASAN_OPTIONS,detect_stack_use_after_return=1"
export ASAN_OPTIONS="$ASAN_OPTIONS,strict_init_order=1"
export ASAN_OPTIONS="$ASAN_OPTIONS,strict_string_checks=1"

View File

@ -28,7 +28,8 @@ cd _build
ninja install -j"$(nproc)"
export TSAN_OPTIONS="halt_on_error=1"
export TSAN_OPTIONS="color=always"
export TSAN_OPTIONS="$TSAN_OPTIONS,halt_on_error=1"
export TSAN_OPTIONS="$TSAN_OPTIONS,second_deadlock_stack=1"
export TSAN_OPTIONS="$TSAN_OPTIONS,symbolize=1"
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6

36
.circleci/cmake-ubsan Executable file
View File

@ -0,0 +1,36 @@
#!/bin/bash
set -eu
CACHEDIR="$HOME/cache"
. ".github/scripts/flags-$CC.sh"
add_flag -Werror
add_flag -fdiagnostics-color=always
add_flag -fno-omit-frame-pointer
add_flag -fno-sanitize-recover=all
add_flag -fsanitize=undefined,nullability,local-bounds,float-divide-by-zero,integer
add_flag -fno-sanitize=implicit-conversion,unsigned-integer-overflow
cmake -B_build -H. -GNinja \
-DCMAKE_C_FLAGS="$C_FLAGS" \
-DCMAKE_CXX_FLAGS="$CXX_FLAGS" \
-DCMAKE_EXE_LINKER_FLAGS="$LD_FLAGS" \
-DCMAKE_SHARED_LINKER_FLAGS="$LD_FLAGS" \
-DCMAKE_INSTALL_PREFIX:PATH="$PWD/_install" \
-DCMAKE_UNITY_BUILD=ON \
-DMIN_LOGGER_LEVEL=TRACE \
-DMUST_BUILD_TOXAV=ON \
-DNON_HERMETIC_TESTS=ON \
-DSTRICT_ABI=ON \
-DTEST_TIMEOUT_SECONDS=120 \
-DUSE_IPV6=OFF \
-DAUTOTEST=ON
cd _build
ninja install -j"$(nproc)"
export UBSAN_OPTIONS="color=always"
export UBSAN_OPTIONS="$UBSAN_OPTIONS,print_stacktrace=1"
export UBSAN_OPTIONS="$UBSAN_OPTIONS,symbolize=1"
ctest -j50 --output-on-failure --rerun-failed --repeat until-pass:6

View File

@ -9,6 +9,7 @@ workflows:
- asan
- tsan
- msan
- ubsan
# Static analysis
- clang-analyze
- clang-tidy
@ -52,6 +53,16 @@ jobs:
- checkout
- run: CC=clang .circleci/cmake-tsan
ubsan:
working_directory: ~/work
docker:
- image: ubuntu
steps:
- run: *apt_install
- checkout
- run: CC=clang .circleci/cmake-ubsan
msan:
working_directory: ~/work
docker:

View File

@ -36,6 +36,7 @@ branches:
- "ci/circleci: msan"
- "ci/circleci: static-analysis"
- "ci/circleci: tsan"
- "ci/circleci: ubsan"
- "cimple"
- "code-review/reviewable"
- "continuous-integration/appveyor/pr"

View File

@ -7,6 +7,7 @@ RUN apt-get update && \
clang \
cmake \
libconfig-dev \
libgtest-dev \
libmsgpack-dev \
libopus-dev \
libsodium-dev \

View File

@ -77,17 +77,19 @@ TEST(PingArray, ZeroLengthDataCanBeAdded) {
Ping_Array_Ptr const arr(ping_array_new(2, 1));
Mono_Time_Ptr const mono_time(mono_time_new());
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), nullptr, 0);
uint8_t c = 0;
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c));
EXPECT_NE(ping_id, 0);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), nullptr, 0, ping_id), 0);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1);
}
TEST(PingArray, PingId0IsInvalid) {
Ping_Array_Ptr const arr(ping_array_new(2, 1));
Mono_Time_Ptr const mono_time(mono_time_new());
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), nullptr, 0, 0), -1);
uint8_t c = 0;
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), 0), -1);
}
// Protection against replay attacks.
@ -95,26 +97,28 @@ TEST(PingArray, DataCanOnlyBeRetrievedOnce) {
Ping_Array_Ptr const arr(ping_array_new(2, 1));
Mono_Time_Ptr const mono_time(mono_time_new());
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), nullptr, 0);
uint8_t c = 0;
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c));
EXPECT_NE(ping_id, 0);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), nullptr, 0, ping_id), 0);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), nullptr, 0, ping_id), -1);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), -1);
}
TEST(PingArray, PingIdMustMatchOnCheck) {
Ping_Array_Ptr const arr(ping_array_new(1, 1));
Mono_Time_Ptr const mono_time(mono_time_new());
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), nullptr, 0);
uint8_t c = 0;
uint64_t const ping_id = ping_array_add(arr.get(), mono_time.get(), &c, sizeof(c));
EXPECT_NE(ping_id, 0);
uint64_t const bad_ping_id = ping_id == 1 ? 2 : 1;
// bad_ping_id will also be pointing at the same element, but won't match the
// actual ping_id.
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), nullptr, 0, bad_ping_id), -1);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), nullptr, 0, ping_id), 0);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), bad_ping_id), -1);
EXPECT_EQ(ping_array_check(arr.get(), mono_time.get(), &c, sizeof(c), ping_id), 1);
}
} // namespace