diff --git a/.circleci/cmake-asan b/.circleci/cmake-asan index a1f8f562..3003ec6f 100755 --- a/.circleci/cmake-asan +++ b/.circleci/cmake-asan @@ -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" diff --git a/.circleci/cmake-tsan b/.circleci/cmake-tsan index 60c2fc0b..ab98e0de 100755 --- a/.circleci/cmake-tsan +++ b/.circleci/cmake-tsan @@ -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 diff --git a/.circleci/cmake-ubsan b/.circleci/cmake-ubsan new file mode 100755 index 00000000..81954ac7 --- /dev/null +++ b/.circleci/cmake-ubsan @@ -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 diff --git a/.circleci/config.yml b/.circleci/config.yml index 28927ea4..aa0a2c39 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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: diff --git a/.github/settings.yml b/.github/settings.yml index 18bcae21..a1294314 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -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" diff --git a/other/docker/circleci/Dockerfile b/other/docker/circleci/Dockerfile index a2a611e0..ba50b0a7 100644 --- a/other/docker/circleci/Dockerfile +++ b/other/docker/circleci/Dockerfile @@ -7,6 +7,7 @@ RUN apt-get update && \ clang \ cmake \ libconfig-dev \ + libgtest-dev \ libmsgpack-dev \ libopus-dev \ libsodium-dev \ diff --git a/toxcore/ping_array_test.cc b/toxcore/ping_array_test.cc index 09836efa..4876ed2a 100644 --- a/toxcore/ping_array_test.cc +++ b/toxcore/ping_array_test.cc @@ -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