From b79d53d5945632d91a64d4bbf84a1e1b384d96cc Mon Sep 17 00:00:00 2001 From: Lindsay Stewart Date: Thu, 8 Jun 2023 01:47:48 -0700 Subject: [PATCH 1/2] Add ThreadSanitizer --- CMakeLists.txt | 29 +++++++++++++++++------------ codebuild/spec/buildspec_tsan.yml | 25 +++++++++++++++++++++++++ tests/.tsan_suppressions | 2 ++ 3 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 codebuild/spec/buildspec_tsan.yml create mode 100644 tests/.tsan_suppressions diff --git a/CMakeLists.txt b/CMakeLists.txt index d0585ef5d0f..342d8d92691 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ option(EXPERIMENTAL_TREAT_WARNINGS_AS_ERRORS "Additional compiler warnings are t indicate danger points where you should verify with the S2N-TLS developers that the security of the library is not compromised. These warnings are currently failing for some builds; once the problems are fixed, they will be moved to UNSAFE_TREAT_WARNINGS_AS_ERRORS." OFF) +option(TSAN "Enable ThreadSanitizer to test thread safety" OFF) # Turn BUILD_TESTING=ON by default include(CTest) @@ -220,6 +221,11 @@ if(S2N_UNSAFE_FUZZING_MODE) target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize-coverage=trace-pc-guard -fsanitize=address,undefined,leak -fuse-ld=gold -DS2N_ADDRESS_SANITIZER=1) endif() +if(TSAN) + target_compile_options(${PROJECT_NAME} PUBLIC -fsanitize=thread) + target_link_options(${PROJECT_NAME} PUBLIC -fsanitize=thread) +endif() + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") if (NOT $ENV{S2N_LIBCRYPTO} MATCHES "awslc") @@ -496,6 +502,16 @@ if (BUILD_TESTING) file (GLOB TEST_LD_PRELOAD "tests/LD_PRELOAD/*.c") add_library(allocator_overrides SHARED ${TEST_LD_PRELOAD}) + set(UNIT_TEST_ENVS S2N_DONT_MLOCK=1) + if(TSAN) + set(TSAN_SUPPRESSIONS_FILE ${CMAKE_SOURCE_DIR}/tests/.tsan_suppressions) + if(NOT EXISTS ${TSAN_SUPPRESSIONS_FILE}) + message(FATAL_ERROR "TSAN suppression file ${TSAN_SUPPRESSIONS_FILE} missing") + endif() + set(UNIT_TEST_ENVS ${UNIT_TEST_ENVS} S2N_ADDRESS_SANITIZER=1) + set(UNIT_TEST_ENVS ${UNIT_TEST_ENVS} TSAN_OPTIONS=suppressions=${TSAN_SUPPRESSIONS_FILE}) + endif() + file(GLOB UNITTESTS_SRC "tests/unit/*.c") foreach(test_case ${UNITTESTS_SRC}) string(REGEX REPLACE ".+\\/(.+)\\.c" "\\1" test_case_name ${test_case}) @@ -519,18 +535,7 @@ if (BUILD_TESTING) endif() add_test(NAME ${test_case_name} COMMAND $ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/unit) set_property(TEST ${test_case_name} PROPERTY LABELS "unit") - - set_property( - TEST - ${test_case_name} - PROPERTY - ENVIRONMENT LD_PRELOAD=$) - - set_property( - TEST - ${test_case_name} - PROPERTY - ENVIRONMENT S2N_DONT_MLOCK=1) + set_property(TEST ${test_case_name} PROPERTY ENVIRONMENT ${UNIT_TEST_ENVS}) endforeach(test_case) diff --git a/codebuild/spec/buildspec_tsan.yml b/codebuild/spec/buildspec_tsan.yml new file mode 100644 index 00000000000..c686b69ef5b --- /dev/null +++ b/codebuild/spec/buildspec_tsan.yml @@ -0,0 +1,25 @@ +--- +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You may not use +# this file except in compliance with the License. A copy of the License is +# located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. See the License for the specific language governing permissions and +# limitations under the License. +version: 0.2 + +phases: + build: + on-failure: ABORT + commands: + - cmake . -Bbuild -DTSAN=on + - cmake --build ./build -j $(nproc) + post_build: + on-failure: ABORT + commands: + - CTEST_PARALLEL_LEVEL=$(nproc) make -C build test diff --git a/tests/.tsan_suppressions b/tests/.tsan_suppressions new file mode 100644 index 00000000000..1498f4ab77e --- /dev/null +++ b/tests/.tsan_suppressions @@ -0,0 +1,2 @@ +# We don't care about the thread safety of our test count +race:test_count From 1ffc31d644f88b7f99c6d3b4998995cb5734dce1 Mon Sep 17 00:00:00 2001 From: Lindsay Stewart Date: Mon, 12 Jun 2023 11:35:41 -0700 Subject: [PATCH 2/2] Address PR comments --- CMakeLists.txt | 1 + codebuild/spec/buildspec_tsan.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 342d8d92691..fe942ccf549 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -511,6 +511,7 @@ if (BUILD_TESTING) set(UNIT_TEST_ENVS ${UNIT_TEST_ENVS} S2N_ADDRESS_SANITIZER=1) set(UNIT_TEST_ENVS ${UNIT_TEST_ENVS} TSAN_OPTIONS=suppressions=${TSAN_SUPPRESSIONS_FILE}) endif() + message(STATUS "Running tests with environment: ${UNIT_TEST_ENVS}") file(GLOB UNITTESTS_SRC "tests/unit/*.c") foreach(test_case ${UNITTESTS_SRC}) diff --git a/codebuild/spec/buildspec_tsan.yml b/codebuild/spec/buildspec_tsan.yml index c686b69ef5b..6aaf00efaa9 100644 --- a/codebuild/spec/buildspec_tsan.yml +++ b/codebuild/spec/buildspec_tsan.yml @@ -22,4 +22,4 @@ phases: post_build: on-failure: ABORT commands: - - CTEST_PARALLEL_LEVEL=$(nproc) make -C build test + - CTEST_OUTPUT_ON_FAILURE=1 CTEST_PARALLEL_LEVEL=$(nproc) make -C build test