From 6bf1d2a03dea76cab1975f20a6a7d3001b1e7ce6 Mon Sep 17 00:00:00 2001 From: Kumar Aditya Date: Wed, 8 Jul 2026 20:45:31 +0530 Subject: [PATCH] gh-143750: Compile OpenSSL with TSan for TSan CI (#153316) Co-authored-by: Sam Gross (cherry picked from commit fc19ad7b8b08c43667c9087d89f32f08830544ce) --- .github/workflows/reusable-san.yml | 63 +++++++++++++++++++++--------- Tools/ssl/multissltests.py | 8 ++++ 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/.github/workflows/reusable-san.yml b/.github/workflows/reusable-san.yml index afe0100c085e5d..317763c65f3c25 100644 --- a/.github/workflows/reusable-san.yml +++ b/.github/workflows/reusable-san.yml @@ -17,6 +17,7 @@ permissions: env: FORCE_COLOR: 1 + OPENSSL_VER: 3.5.7 jobs: build-san-reusable: @@ -45,28 +46,53 @@ jobs: sudo update-alternatives --set clang /usr/bin/clang-20 sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-20 100 sudo update-alternatives --set clang++ /usr/bin/clang++-20 - - if [ "${SANITIZER}" = "TSan" ]; then - # Reduce ASLR to avoid TSan crashing - sudo sysctl -w vm.mmap_rnd_bits=28 - fi - - - name: Sanitizer option setup - run: | - if [ "${SANITIZER}" = "TSan" ]; then - echo "TSAN_OPTIONS=${SAN_LOG_OPTION} suppressions=${GITHUB_WORKSPACE}/Tools/tsan/suppressions${{ - fromJSON(inputs.free-threading) - && '_free_threading' - || '' - }}.txt handle_segv=0" >> "$GITHUB_ENV" - else - echo "UBSAN_OPTIONS=${SAN_LOG_OPTION}" >> "$GITHUB_ENV" - fi echo "CC=clang" >> "$GITHUB_ENV" echo "CXX=clang++" >> "$GITHUB_ENV" + - name: TSan option setup + if: inputs.sanitizer == 'TSan' + run: | + sudo sysctl -w vm.mmap_rnd_bits=28 # Reduce ASLR to avoid TSan crashing + + echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV" + echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> "$GITHUB_ENV" + echo "TSAN_OPTIONS=${SAN_LOG_OPTION} suppressions=${GITHUB_WORKSPACE}/Tools/tsan/suppressions${SUPPRESSIONS_SUFFIX}.txt handle_segv=0" >> "$GITHUB_ENV" env: - SANITIZER: ${{ inputs.sanitizer }} SAN_LOG_OPTION: log_path=${{ github.workspace }}/san_log + SUPPRESSIONS_SUFFIX: >- + ${{ + fromJSON(inputs.free-threading) + && '_free_threading' + || '' + }} + - name: UBSan option setup + if: inputs.sanitizer != 'TSan' + run: >- + echo + "UBSAN_OPTIONS=${SAN_LOG_OPTION}" + >> "$GITHUB_ENV" + env: + SAN_LOG_OPTION: log_path=${{ github.workspace }}/san_log + - name: Add ccache to PATH + run: | + echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV" + - name: 'Restore OpenSSL build (TSan)' + id: cache-openssl + if: inputs.sanitizer == 'TSan' + uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4 + with: + path: ./multissl/openssl/${{ env.OPENSSL_VER }} + key: ${{ env.IMAGE_OS_VERSION }}-multissl-openssl-tsan-${{ env.OPENSSL_VER }} + - name: Install OpenSSL (TSan) + if: >- + inputs.sanitizer == 'TSan' + && steps.cache-openssl.outputs.cache-hit != 'true' + run: >- + python3 Tools/ssl/multissltests.py + --steps=library + --base-directory="${MULTISSL_DIR}" + --openssl="${OPENSSL_VER}" + --system=Linux + --tsan - name: Configure CPython run: >- ./configure @@ -77,6 +103,7 @@ jobs: || '--with-undefined-behavior-sanitizer' }} --with-pydebug + ${{ inputs.sanitizer == 'TSan' && '--with-openssl="$OPENSSL_DIR" --with-openssl-rpath=auto' || '' }} ${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }} - name: Build CPython run: make -j4 diff --git a/Tools/ssl/multissltests.py b/Tools/ssl/multissltests.py index 68bd6e0860deb6..cb349236a034c4 100755 --- a/Tools/ssl/multissltests.py +++ b/Tools/ssl/multissltests.py @@ -147,6 +147,12 @@ dest='keep_sources', help="Keep original sources for debugging." ) +parser.add_argument( + '--tsan', + action='store_true', + dest='tsan', + help="Build with thread sanitizer. (Disables fips in OpenSSL 3.x)." +) class AbstractBuilder(object): @@ -301,6 +307,8 @@ def _build_src(self, config_args=()): """Now build openssl""" log.info("Running build in {}".format(self.build_dir)) cwd = self.build_dir + if self.args.tsan: + config_args += ("-fsanitize=thread",) cmd = [ "./config", *config_args, "shared", "--debug",