Conversation
--config=asan compiled and linked C++ with -fsanitize=address but built Rust without -Zsanitizer=address, so Rust code ran uninstrumented. Nightly rustc also refuses to link sanitizer-instrumented crates against an uninstrumented standard library, so the flag alone is not enough. - Generalize the TSan Rust toolchain macro into sanitizer_rust_toolchain (build/rust/sanitizer_toolchain.bzl) and define ASan toolchains, each with an ASan-built standard library, for Linux x86_64, Linux aarch64 (the ci-linux-arm-asan config) and macOS arm64. - --config=asan registers them and adds -Zsanitizer=address; -Zexternal-clangrt moves to sanitizer-common so Rust shares Clang's runtime under both sanitizers. - macOS: Apple Clang's ASan runtime exports __asan_version_mismatch_check_apple_clang_<version> rather than upstream LLVM's __asan_version_mismatch_check_v8 that rustc references, so the macOS ASan toolchain disables the version guard. build_std gains a rustflags input so the standard library is built with the same flags. - Add //src/rust/asan:heap_buffer_overflow, which checks that an out-of-bounds read in Rust code is reported. It runs the read in a child process because __asan_on_error cannot be overridden from the executable when the runtime is a dylib. - Remove the dead ASan test in cxx-integration-test (gated on a feature nothing set, importing a crate that does not exist) and update src/rust/cxx/AGENTS.md. Co-Authored-By: Claude Code <noreply@anthropic.com>
Contributor
|
@danlapid Bonk workflow was cancelled. View workflow run · To retry, trigger Bonk again. |
UndefinedBehaviorSanitizer, unlike ASan and TSan, can share a build with either, so enable it for C++ in the existing ASan configuration instead of adding a CI lane. Tests halt on the first report with a stack trace. It instruments C++ only: rustc has no UBSan. Co-Authored-By: Claude Code <noreply@anthropic.com>
Enabling UndefinedBehaviorSanitizer in --config=asan surfaced four reports that fail jsg-test, buffer-nodejs-test, string-decoder-test and server-test: - src/rust/jsg/ffi.c++: the typed-array constructors memcpy() into a zero-length backing store, whose Data() is null. Skip the copy when the array is empty. - src/workerd/api/node/buffer.c++: the UTF-16 paths of writeInto() and toStringImpl() copied through kj::ArrayPtr<uint16_t> views of byte buffers that can sit at odd offsets, so the element-wise copy did misaligned uint16_t loads and stores. Copy through asBytes() instead; the aligned temporary each path already used now carries the data both ways. - capnp's lexer memcpy()s from a null source for an empty backtick-quoted line. capnp-cpp is a github_tarball dependency, which update-deps.py cannot attach patches to, so --config=asan drops the nonnull-attribute check for that one file until the fix lands upstream. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
danlapid
force-pushed
the
dlapid/rust-asan
branch
from
September 21, 2026 03:46
e53057e to
26ab43b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
--config=asancompiled and linked C++ with-fsanitize=addressbut built Rust without-Zsanitizer=address, so Rust code ran uninstrumented. Nightly rustc also refuses to link sanitizer-instrumented crates against an uninstrumented standard library, so adding the flag alone is not enough. ASan needs a toolchain like the one TSan already has.Changes
build/rust/sanitizer_toolchain.bzlreplacestsan_toolchain.bzl.sanitizer_rust_toolchain(name, sanitizer, host)builds the toolchain for either sanitizer, with the per-host settings in one table.//build/rustnow definesasan_toolchain_{linux_x86_64,linux_aarch64,macos_aarch64}; the TSan toolchain names are unchanged..bazelrc:asanregisters the ASan toolchains and adds-Zsanitizer=address.-Zexternal-clangrtmoves tosanitizer-common, so Rust uses Clang's runtime under both sanitizers.rust.MODULE.bazel: exposesrust_nightly_linux_aarch64for theci-linux-arm-asanconfig.__asan_version_mismatch_check_apple_clang_<version>instead of upstream LLVM's__asan_version_mismatch_check_v8, which rustc references. The macOS ASan toolchain passes-Cllvm-args=-asan-guard-against-version-mismatch=false.build_stdgets arustflagsinput so the standard library is built with the same flag.//src/rust/asan:heap_buffer_overflowchecks that an out-of-bounds read in Rust code is reported. The read runs in a child process because__asan_on_errorcan't be overridden from the executable when the runtime is a dylib (macOS).cxx-integration-test, which was gated on a feature nothing set and imported a crate that doesn't exist. Also updates the ASan note insrc/rust/cxx/AGENTS.md.Testing
On macOS arm64 with
--config=asan://src/rust/asan:heap_buffer_overflow,//src/rust/cxx/tests:test,//src/rust/cxx-integration-test:all,//src/rust/tsan:tokio_test,//src/rust/tsan:clone_fd.-Cllvm-args=-asan-instrument-reads=false, the new test fails with "did not detect", so it really checks that Rust code is instrumented.Not run locally on Linux; the x64 ASan CI job covers that.
Second commit: UBSan in
--config=asanASan and TSan can't be built into the same binary, but UBSan can share a build with either. So
--config=asannow uses-fsanitize=address,undefinedfor C++, and tests stop at the first UBSan report (UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1). rustc has no UBSan, so this covers C++ only.Testing on macOS arm64:
//src/rust/...,//src/workerd/util/...and//src/workerd/jsg/...that don't depend on V8 pass, with no UBSan reports.mksnapshotbinds__asan_get_shadow_mappingtolibsystem_sanitizersinstead of Clang's runtime and segfaults inV8::Initialize. This happens with or without UBSan.The x64 ASan CI job is the first real UBSan check for V8 and the rest of workerd. If it reports issues in third-party code, we can turn off specific checks or exclude those files.
🤖 Generated with Claude Code