Enable rust address sanitizer for asan ci job (#9643)

Rust has multiple sanitizers available (with llvm integration).
-Zsanitizer=address catches the most likely culprits but we may want to set up a
separate job w/ -Zsanitizer=memory to catch uninitialized reads.

It might be necessary to execute `cargo build` as `cargo build -Zbuild-std` to
get full coverage.

When we're linking against the hybrid C++ codebase, the sanitizer library is
injected into the binary by also include `-fsanitize=address` in CXXFLAGS - we
do *not* want to manually opt-into `-lasan`. We also need to manually specify
the desired target triple as a CMake variable and then explicitly pass it to all
`cargo` invocations if building with ASAN.

Corrosion has been patched to make sure it follows these rules.

The `cargo-test` target is failing to link under ASAN. For some reason it has
autocxx/ffi dependencies even though only rust-native, ffi-free code should be
tested (and one would think the situation wouldn't change depending on the
presence of the sanitizer flag). It's been disabled under ASAN for now.
This commit is contained in:
Mahmoud Al-Qudsi 2023-03-06 18:15:36 -06:00 committed by GitHub
parent 307c58dd07
commit 91cf526d23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 11 deletions

View file

@ -73,13 +73,22 @@ jobs:
ubuntu-asan:
runs-on: ubuntu-latest
env:
# Rust has two different memory sanitizers of interest; they can't be used at the same time:
# * AddressSanitizer detects out-of-bound access, use-after-free, use-after-return,
# use-after-scope, double-free, invalid-free, and memory leaks.
# * MemorySanitizer detects uninitialized reads.
#
RUSTFLAGS: "-Zsanitizer=address"
# RUSTFLAGS: "-Zsanitizer=memory -Zsanitizer-memory-track-origins"
steps:
- uses: actions/checkout@v3
- name: SetupRust
uses: ATiltedTree/setup-rust@v1
with:
rust-version: 1.67
# All -Z options require running nightly
rust-version: nightly
- name: Install deps
run: |
sudo apt install gettext libncurses5-dev libpcre2-dev python3-pip tmux
@ -91,7 +100,9 @@ jobs:
CXXFLAGS: "-fno-omit-frame-pointer -fsanitize=undefined -fsanitize=address -DFISH_CI_SAN"
run: |
mkdir build && cd build
cmake ..
# Rust's ASAN requires the build system to explicitly pass a --target triple. We read that
# value from CMake variable Rust_CARGO_TARGET (shared with corrosion).
cmake .. -DASAN=1 -DRust_CARGO_TARGET=x86_64-unknown-linux-gnu
- name: make
run: |
make

View file

@ -5,7 +5,7 @@ set(CORROSION_TESTS OFF CACHE BOOL "" FORCE)
FetchContent_Declare(
Corrosion
GIT_REPOSITORY https://github.com/ridiculousfish/corrosion
GIT_REPOSITORY https://github.com/mqudsi/corrosion
GIT_TAG fish
)

View file

@ -177,17 +177,32 @@ foreach(PEXPECT ${PEXPECTS})
endforeach(PEXPECT)
# Rust stuff.
add_test(
NAME "cargo-test"
COMMAND cargo test --target-dir target
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/fish-rust"
)
set_tests_properties("cargo-test" PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
add_test_target("cargo-test")
if(DEFINED ASAN)
# Rust w/ -Zsanitizer=address requires explicitly specifying the --target triple or else linker
# errors pertaining to asan symbols will ensue.
if(NOT DEFINED Rust_CARGO_TARGET)
message(FATAL_ERROR "ASAN requires defining the CMake variable Rust_CARGO_TARGET to the
intended target triple")
endif()
set(cargo_target_opt "--target" ${Rust_CARGO_TARGET})
endif()
# cargo-test is failing to link w/ ASAN enabled. For some reason it is picking up autocxx ffi
# dependencies, even though `carg test` is supposed to be for rust-only code w/ no ffi dependencies.
# TODO: Figure this out and fix it.
if(NOT DEFINED ASAN)
add_test(
NAME "cargo-test"
COMMAND cargo test --target-dir target ${cargo_target_opt}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/fish-rust"
)
set_tests_properties("cargo-test" PROPERTIES SKIP_RETURN_CODE ${SKIP_RETURN_CODE})
add_test_target("cargo-test")
endif()
add_test(
NAME "cargo-test-widestring"
COMMAND cargo test --target-dir target
COMMAND cargo test --target-dir target ${cargo_target_opt}
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/fish-rust/widestring-suffix/"
)
add_test_target("cargo-test-widestring")