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

Enable ASan, TSan, UBSan for aarch64-apple-darwin. #79883

Merged
merged 10 commits into from
Jan 2, 2021
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,7 +895,7 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) {
.unwrap_or_default();

match sess.opts.target_triple.triple() {
"x86_64-apple-darwin" => {
"aarch64-apple-darwin" | "x86_64-apple-darwin" => {
// On Apple platforms, the sanitizer is always built as a dylib, and
// LLVM will link to `@rpath/*.dylib`, so we need to specify an
// rpath to the library as well (the rpath should be absolute, see
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1517,18 +1517,24 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}

const ASAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-fuchsia",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-fuchsia",
"x86_64-unknown-freebsd",
"x86_64-unknown-linux-gnu",
];
const LSAN_SUPPORTED_TARGETS: &[&str] =
&["aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"];
const LSAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
];
const MSAN_SUPPORTED_TARGETS: &[&str] =
&["aarch64-unknown-linux-gnu", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu"];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not MSAN :-)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I returned my new Macbook Air (need more memory and waiting for the new one to ship), so I can't easily confirm, but I recall there being an error message saying macOS is not supported by MSan, which is maybe why x86_64-apple-darwin is also not listed here. These docs also back up this claim

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I clearly have the reading comprehension of a goldfish, I totally missed that no macOS platforms were there.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/llvm/llvm-project/blob/62ec4ac90738a5f2d209ed28c822223e58aaaeb7/compiler-rt/cmake/config-ix.cmake#L696-L701

if (COMPILER_RT_HAS_SANITIZER_COMMON AND MSAN_SUPPORTED_ARCH AND
    OS_NAME MATCHES "Linux|FreeBSD|NetBSD")
  set(COMPILER_RT_HAS_MSAN TRUE)
else()
  set(COMPILER_RT_HAS_MSAN FALSE)
endif()

const TSAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-unknown-freebsd",
Expand Down
36 changes: 27 additions & 9 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,15 +356,12 @@ fn copy_sanitizers(
let dst = libdir.join(&runtime.name);
builder.copy(&runtime.path, &dst);

if target == "x86_64-apple-darwin" {
// Update the library install name reflect the fact it has been renamed.
let status = Command::new("install_name_tool")
.arg("-id")
.arg(format!("@rpath/{}", runtime.name))
.arg(&dst)
.status()
.expect("failed to execute `install_name_tool`");
assert!(status.success());
if target == "x86_64-apple-darwin" || target == "aarch64-apple-darwin" {
// Update the library’s install name to reflect that it has has been renamed.
apple_darwin_update_library_name(&dst, &format!("@rpath/{}", &runtime.name));
// Upon renaming the install name, the code signature of the file will invalidate,
// so we will sign it again.
Comment on lines +362 to +363
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow this. Renaming other signed files doesn't cause problems; why does this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renaming the file with mv doesn't invalidate the signature, but renaming the install name (within the contents of the file) with install_name_tool does invalidate.

Searching for "install_name_tool invalidate signature" on Google returns other projects that have hit this. For example: https://community.intel.com/t5/Intel-oneAPI-Threading-Building/Mac-install-location-conflicts-with-code-signing/m-p/1008483/highlight/true#M12505

apple_darwin_sign_file(&dst);
}

target_deps.push(dst);
Expand All @@ -373,6 +370,27 @@ fn copy_sanitizers(
target_deps
}

fn apple_darwin_update_library_name(library_path: &Path, new_name: &str) {
let status = Command::new("install_name_tool")
.arg("-id")
.arg(new_name)
.arg(library_path)
.status()
.expect("failed to execute `install_name_tool`");
assert!(status.success());
}

fn apple_darwin_sign_file(file_path: &Path) {
let status = Command::new("codesign")
.arg("-f") // Force to rewrite the existing signature
.arg("-s")
.arg("-")
.arg(file_path)
.status()
.expect("failed to execute `codesign`");
assert!(status.success());
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct StartupObjects {
pub compiler: Compiler,
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,7 @@ fn supported_sanitizers(
};

match &*target.triple {
"aarch64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]),
"aarch64-fuchsia" => common_libs("fuchsia", "aarch64", &["asan"]),
"aarch64-unknown-linux-gnu" => {
common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan"])
Expand Down
28 changes: 26 additions & 2 deletions src/doc/unstable-book/src/compiler-flags/sanitizer.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ with runtime flag `ASAN_OPTIONS=detect_leaks=1` on macOS.

AddressSanitizer is supported on the following targets:

* `aarch64-apple-darwin`
* `aarch64-fuchsia`
* `aarch64-unknown-linux-gnu`
* `x86_64-apple-darwin`
* `x86_64-fuchsia`
* `x86_64-unknown-freebsd`
* `x86_64-unknown-linux-gnu`

AddressSanitizer works with non-instrumented code although it will impede its
Expand Down Expand Up @@ -169,10 +174,26 @@ Shadow byte legend (one shadow byte represents 8 application bytes):
==39249==ABORTING
```

# LeakSanitizer

LeakSanitizer is run-time memory leak detector.

LeakSanitizer is supported on the following targets:

* `aarch64-apple-darwin`
* `aarch64-unknown-linux-gnu`
* `x86_64-apple-darwin`
* `x86_64-unknown-linux-gnu`

# MemorySanitizer

MemorySanitizer is detector of uninitialized reads. It is only supported on the
`x86_64-unknown-linux-gnu` target.
MemorySanitizer is detector of uninitialized reads.

MemorySanitizer is supported on the following targets:

* `aarch64-unknown-linux-gnu`
* `x86_64-unknown-freebsd`
* `x86_64-unknown-linux-gnu`

MemorySanitizer requires all program code to be instrumented. C/C++ dependencies
need to be recompiled using Clang with `-fsanitize=memory` option. Failing to
Expand Down Expand Up @@ -219,7 +240,10 @@ $ cargo run -Zbuild-std --target x86_64-unknown-linux-gnu
ThreadSanitizer is a data race detection tool. It is supported on the following
targets:

* `aarch64-apple-darwin`
* `aarch64-unknown-linux-gnu`
* `x86_64-apple-darwin`
* `x86_64-unknown-freebsd`
* `x86_64-unknown-linux-gnu`

To work correctly ThreadSanitizer needs to be "aware" of all synchronization
Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/sanitizer-no-sanitize.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Verifies that no_sanitze attribute can be used to
// Verifies that no_sanitize attribute can be used to
// selectively disable sanitizer instrumentation.
//
// needs-sanitizer-address
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/sanitize/unsupported-target.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: `-Zsanitizer=leak` only works with targets: aarch64-unknown-linux-gnu, x86_64-apple-darwin, x86_64-unknown-linux-gnu
error: `-Zsanitizer=leak` only works with targets: aarch64-apple-darwin, aarch64-unknown-linux-gnu, x86_64-apple-darwin, x86_64-unknown-linux-gnu

error: aborting due to previous error

10 changes: 8 additions & 2 deletions src/tools/compiletest/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ const ARCH_TABLE: &[(&str, &str)] = &[
];

pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-fuchsia",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
Expand All @@ -90,13 +91,18 @@ pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
"x86_64-unknown-linux-gnu",
];

pub const LSAN_SUPPORTED_TARGETS: &[&str] =
&["aarch64-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu"];
pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
];

pub const MSAN_SUPPORTED_TARGETS: &[&str] =
&["aarch64-unknown-linux-gnu", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu"];

pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
"x86_64-apple-darwin",
"x86_64-unknown-freebsd",
Expand Down