Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible ASan runtimes when Rust executable links with C shared library that dynamic links asan runtime #114127

Closed
hehaoqian opened this issue Jul 27, 2023 · 3 comments
Labels
A-sanitizers Area: Sanitizers for correctness and code quality T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@hehaoqian
Copy link
Contributor

hehaoqian commented Jul 27, 2023

Issues:

  1. Address sanitized Rust program can compile, but fails to run,
    when it links a shared library that dynamic links to libasan.so,
    which is provided by gcc 7.5
  2. The error message is
==82818==Your application is linked against incompatible ASan runtimes.
  1. It can run with expected result if the shared lib static links to asan runtime, by -static-libasan in C link flags

The cause:

  1. When using RUSTFLAGS=-Zsanitizer=address, it seems rustc always static links asan runtime,
    by static link librustc-nightly_rt.asan.a bundled with rustc installation
  2. I think static links libasan, is not compatible with dynamic linked libasan
  3. I don't think rustc provides a way to opt out of static linking librustc-nightly_rt.asan.a

Compatibility of asan runtimes of gcc7.5.0 and rustc

  1. The version of asan in gcc7.5.0 is 8
    According to __asan_version_mismatch_check_v8 in https://github.com/gcc-mirror/gcc/blob/releases/gcc-7.5.0/libsanitizer/asan/asan_init_version.h
  2. The version of asan in rustc is also 8.
    According to GetAsanVersion function in https://github.com/rust-lang/llvm-project/blob/rustc/16.0-2023-06-05/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Steps to reproduce

// segfault.c
int segfault(void) {
        return *(int *)0x41414141;
}

Create C shared lib by gcc -shared -fPIC segfault.c -o libsegfault.so -fsanitize=address

// build.rs
fn main() {
    println!("cargo:rustc-link-search=.");
    println!("cargo:rustc-link-lib=segfault");
}
// src/main.rs
extern "C" {
    fn segfault() -> i32;
}
fn main() {
    println!("Hello world!");
    unsafe { segfault() };
}

Producing Rust executable with

RUSTFLAGS="-Z sanitizer=address"  cargo +nightly build -Z build-std

Then run the final executable, set environment variable LD_LIBRARY_PATH if needed


Actual result:

==82818==Your application is linked against incompatible ASan runtimes.

Expected result:

==108960==ERROR: AddressSanitizer: SEGV on unknown address 0x000041414141 

Meta

Target platform: x86_64-unknown-linux-gnu

rustc --version --verbose:

rustc 1.73.0-nightly (399b06823 2023-07-20)

gcc --version

gcc (GCC) 7.5.0

Extra notes:

I asked ChatGPT

gcc address sanitizer, shared link or static link?

It answers:

When using the GCC (GNU Compiler Collection) AddressSanitizer (ASan),
it is generally recommended to use it with shared libraries (dynamic linking) rather than static linking.
AddressSanitizer is a powerful runtime memory error detector that can find various memory-related issues like out-of-bounds access, use-after-free, and memory leaks.

@hehaoqian hehaoqian added the C-bug Category: This is a bug. label Jul 27, 2023
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 27, 2023
@saethlin saethlin added A-sanitizers Area: Sanitizers for correctness and code quality T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. C-bug Category: This is a bug. labels Jul 29, 2023
@ObsidianMinor
Copy link
Contributor

ObsidianMinor commented Mar 29, 2024

I'm also encountering this issue. We're trying to link to C++ (clang) that's instrumented for ASAN, but Rust's custom ASAN library doesn't include CXX compiler runtime features. So linking fails for missing symbols. We can't dynamically link the C++ code to ASAN either because both will have duplicate symbols. If you ignore the duplicate symbols weird things happen if you try to build a Rust binary. We need a way to tell rustc to not link it's ASAN library so we can link in our own through another linker flag.

@ObsidianMinor
Copy link
Contributor

Actually it turns out this has been fixed recently with #121207. Now you can avoid linking librustc-nightly_rt.asan.a. Might fix this case too.

@rcvalle
Copy link
Member

rcvalle commented Aug 2, 2024

This seems to have been fixed in #121207. Closing.

@rcvalle rcvalle closed this as completed Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-sanitizers Area: Sanitizers for correctness and code quality T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants