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

sanitizers: Stabilize AddressSanitizer and LeakSanitizer for the Tier 1 targets #123617

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

rcvalle
Copy link
Member

@rcvalle rcvalle commented Apr 8, 2024

Add support for specifying stable sanitizers in addition to the existing supported sanitizers, remove the -Zsanitizer unstable option and have only the -Csanitize codegen option, requiring the -Zunstable-options to be passed for using unstable sanitizers, add AddressSanitizer and LeakSanitizer for the Tier 1 targets that support them, and also stabilize the no_sanitize attribute so stable sanitizers can also be selectively disabled for annotated functions.. The tracking issue for stabilizing the sanitizers is #123615. This is part of our work to stabilize support for sanitizers in the Rust compiler. (See our roadmap at https://hackmd.io/@rcvalle/S1Ou9K6H6.)

Stabilization Report

Summary

We would like to propose stabilizing AddressSanitizer and LeakSanitizer for the Tier 1 targets that support them, and stabilize the no_sanitize attribute so stable sanitizers can also be selectively disabled for annotated functions.. This will be done by

  • Add support for specifying stable sanitizers in addition to the existing supported sanitizers.
  • Removing the -Zsanitizer unstable option and having only the -Csanitize codegen option, and requiring the -Zunstable-options to be passed for using unstable sanitizers.
  • Adding these sanitizers to the stable sanitizers.
  • Stabilize the no_sanitize attribute.

After stabilizing these sanitizers, the supported sanitizers will look like this:

Target Supported Sanitizers (Stable) Supported Sanitizers (Unstable)
aarch64-apple-darwin address cfi, thread
aarch64-apple-ios address, thread
aarch64-apple-ios-macabi address, leak, thread
aarch64-apple-ios-sim address, thread
aarch64-apple-visionos address, thread
aarch64-apple-visionos-sim address, thread
aarch64-linux-android address, cfi, hwaddress, memtag, shadow-call-stack
aarch64-unknown-freebsd address, cfi, memory, thread
aarch64-unknown-fuchsia address, cfi, shadow-call-stack
aarch64-unknown-illumos address, cfi
aarch64-unknown-linux-gnu address, leak cfi, hwaddress, kcfi, memory, memtag, thread
aarch64-unknown-linux-musl address, cfi, leak, memory, thread
aarch64-unknown-linux-ohos address, cfi, hwaddress, leak, memory, memtag, thread
aarch64-unknown-none kcfi, kernel-address
arm-linux-androideabi address
arm64e-apple-darwin address, cfi, thread
arm64e-apple-ios address, thread
armv7-linux-androideabi address
i586-pc-windows-msvc address
i586-unknown-linux-gnu address
i686-linux-android address
i686-pc-windows-msvc address
i686-unknown-linux-gnu address
loongarch64-unknown-linux-gnu address, cfi, leak, memory, thread
loongarch64-unknown-linux-musl address, cfi, leak, memory, thread
loongarch64-unknown-linux-ohos address, cfi, leak, memory, thread
riscv64-linux-android address
riscv64gc-unknown-fuchsia shadow-call-stack
riscv64gc-unknown-none-elf kernel-address, shadow-call-stack
riscv64gc-unknown-nuttx-elf kernel-address
riscv64imac-unknown-none-elf kernel-address, shadow-call-stack
riscv64imac-unknown-nuttx-elf kernel-address
s390x-unknown-linux-gnu address, leak, memory, thread
s390x-unknown-linux-musl address, leak, memory, thread
thumbv7neon-linux-androideabi address
x86_64-apple-darwin address, leak cfi, thread
x86_64-apple-ios address, thread
x86_64-apple-ios-macabi address, leak, thread
x86_64-linux-android address
x86_64-pc-solaris address, cfi, thread
x86_64-pc-windows-msvc address
x86_64-unknown-freebsd address, cfi, memory, thread
x86_64-unknown-fuchsia address, cfi, leak
x86_64-unknown-illumos address, cfi, thread
x86_64-unknown-linux-gnu address, leak cfi, dataflow, kcfi, memory, safestack, thread
x86_64-unknown-linux-musl address, cfi, leak, memory, thread
x86_64-unknown-linux-ohos address, cfi, leak, memory, thread
x86_64-unknown-netbsd address, cfi, leak, memory, thread
x86_64-unknown-none kcfi, kernel-address
x86_64h-apple-darwin address, cfi, leak, thread

The tracking issue for stabilizing the sanitizers is #123615. This is part of our work to stabilize support for sanitizers in the Rust compiler. (See our roadmap at https://hackmd.io/@rcvalle/S1Ou9K6H6.)

Documentation

Documentation will be updated by adding documentation for the -Csanitizer codegen option to the Codegen Options in the The rustc book.

Tests

You may find current and will find additional test cases for the sanitizers in:

Unresolved questions

  • Doesn't the sanitizers require rebuilding the Rust Standard Library (i.e., Cargo build-std feature)?
    We will prioritize stabilizing sanitizers that provide incremental value without requiring rebuilding the Rust Standard Library (i.e., Cargo build-std feature). We're also working on Partial compilation using MIR-only rlibs compiler-team#738, which should help with -Zbuild-std.

@rustbot
Copy link
Collaborator

rustbot commented Apr 8, 2024

r? @compiler-errors

rustbot has assigned @compiler-errors.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-testsuite Area: The testsuite used to check the correctness of rustc S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 8, 2024
@rustbot
Copy link
Collaborator

rustbot commented Apr 8, 2024

Some changes occurred in src/tools/compiletest

cc @jieyouxu

These commits modify compiler targets.
(See the Target Tier Policy.)

@rcvalle
Copy link
Member Author

rcvalle commented Apr 8, 2024

r? @davidtwco

@rust-log-analyzer

This comment has been minimized.

Copy link
Member

@compiler-errors compiler-errors left a comment

Choose a reason for hiding this comment

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

I'd like to see tests that exercise things like -Csanitizer=non-existent and -Zsanitizer=non-existent, and also -Zsanitizer=stable-sanitizer1 (e.g. an x86_64-unknown-linux-gnu test for a stable sanitizer) and -Csanitizer=unstable-sanitizer (I believe you can add a run-make test with a custom target that has no sanitizers enabled for it?)

Footnotes

  1. What do we do if we pass -Zsanitizer with a stable sanitizer? Should we error? Presumably not, but I would assume we'd want to at least warn the users that the sanitizer has been stabilized and they should be using -C, just like we do for feature gates.

compiler/rustc_session/src/options.rs Outdated Show resolved Hide resolved
compiler/rustc_target/src/spec/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_target/src/spec/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_target/src/spec/mod.rs Outdated Show resolved Hide resolved
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 8, 2024
@tgross35
Copy link
Contributor

tgross35 commented Apr 8, 2024

Documentation will need an update. Is something like -Csanitizer=address,memory expected to work (like LLVM) ordoes it need to be -Csanitizer=address -Dsanitizer=memory?

@Noratrieb
Copy link
Member

This is unusable to most stable Rust users, right? It requires either -Zbuild-std or a custom toolchain with an instrumented standard library. The documentation in the rustc book and the stabilization report/description (which you need to add) should mention this very clearly.

@rust-log-analyzer

This comment has been minimized.

@bors

This comment was marked as resolved.

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from cec660e to 17eff53 Compare April 17, 2024 18:15
@rust-log-analyzer

This comment has been minimized.

@bors

This comment was marked as resolved.

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from 17eff53 to f81f25d Compare April 23, 2024 02:49
@rustbot rustbot added the T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue. label Apr 23, 2024
@rustbot
Copy link
Collaborator

rustbot commented Apr 23, 2024

Some changes occurred in cfg and check-cfg configuration

cc @Urgau

Some changes occurred in tests/ui/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

Some changes occurred in tests/codegen/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

@rust-log-analyzer

This comment has been minimized.

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from f81f25d to 2cfed6e Compare April 24, 2024 01:28
@madsmtm
Copy link
Contributor

madsmtm commented Nov 12, 2024

I'll also add that LLVM's own documentation does not yet list Aarch64 as a supported platform for AddressSanitizer:
https://github.com/llvm/llvm-project/blob/llvmorg-19.1.3/clang/docs/AddressSanitizer.rst?plain=1#L316-L329

EDIT: A few more concerns:

  • Does this work with other codegen backends like Cranelift? If not, then I fear stabilizing this now may make it harder for Cargo to move to using Cranelift in debug mode by default in the future.
    • Perhaps we need to also require -Zcodegen-backend=llvm or similar before you can enable sanitizers?
  • Who are the LLVM developers that maintain these sanitizers? Are they aware that Rust is stabilizing them, and if not, could we tag them?

@rcvalle
Copy link
Member Author

rcvalle commented Nov 14, 2024

I'll also add that LLVM's own documentation does not yet list Aarch64 as a supported platform for AddressSanitizer: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.3/clang/docs/AddressSanitizer.rst?plain=1#L316-L329

Thanks for pointing this out! @vitalybuka, do you think we should list it there (assuming it's supported)?

EDIT: A few more concerns:

  • Does this work with other codegen backends like Cranelift? If not, then I fear stabilizing this now may make it harder for Cargo to move to using Cranelift in debug mode by default in the future.

I don't think these would work with other backends than LLVM as these are mostly implemented in LLVM.

  • Perhaps we need to also require -Zcodegen-backend=llvm or similar before you can enable sanitizers?

We could just show an error message saying these are not available when using a backend other than LLVM? (Which I think is what happens now, but I need to confirm.) What do you think?

  • Who are the LLVM developers that maintain these sanitizers? Are they aware that Rust is stabilizing them, and if not, could we tag them?

Yes, @vitalybuka is already participating on this thread.

@madsmtm
Copy link
Contributor

madsmtm commented Nov 14, 2024

We could just show an error message saying these are not available when using a backend other than LLVM? (Which I think is what happens now, but I need to confirm.) What do you think?

The problem is that then it still becomes a breaking change if we want to use Cranelift by default in the future, since with what we're stabilizing e.g. rustc -Csanitize=address will work before, and later it'll error because sanitizers aren't supported in Cranelift. If we required the user to type rustc -Csanitize=address -Ccodegen-backend=llvm up front, it wouldn't be a problem.

Does that make sense? Not sure I explained it right.

In any case, I don't know the plans for Cranelift, and it might already be impossible to make default for other reasons, just a thought.

vitalybuka added a commit to llvm/llvm-project that referenced this pull request Nov 15, 2024
Full list is quite long, and quality of implementation can
vary.

Drop the lists to avoid confusion like
rust-lang/rust#123617 (comment)

We don't maintain these for other sanitizers.
@rcvalle
Copy link
Member Author

rcvalle commented Nov 16, 2024

FYI, @vitalybuka dropped the list of supported architectures on llvm/llvm-project/pull/116302 as per your feedback since it was incomplete and the actual list is quite long.

The problem is that then it still becomes a breaking change if we want to use Cranelift by default in the future, since with what we're stabilizing e.g. rustc -Csanitize=address will work before, and later it'll error because sanitizers aren't supported in Cranelift. If we required the user to type rustc -Csanitize=address -Ccodegen-backend=llvm up front, it wouldn't be a problem.

Does that make sense? Not sure I explained it right.

Yes, I understand. Do you know if there isn't such case of a stabilized flag already? For example, I see a few mentions to LLVM already in https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units (e.g., codegen-units, control-flow-guard, embed-bitcode, etc.). Those all seem to be similar cases that would need to be reimplemented if we replace the default backend so they won't become a breaking change as well.

Given this, I'm not sure whether adding another unstable option to the compiler, and requiring the user to pass an additional option to be able to use the sanitizers is worth it. What do you think?

@madsmtm
Copy link
Contributor

madsmtm commented Nov 16, 2024

The problem is that then it still becomes a breaking change if we want to use Cranelift by default in the future, since with what we're stabilizing e.g. rustc -Csanitize=address will work before, and later it'll error because sanitizers aren't supported in Cranelift. If we required the user to type rustc -Csanitize=address -Ccodegen-backend=llvm up front, it wouldn't be a problem.

Does that make sense? Not sure I explained it right.

Yes, I understand. Do you know if there isn't such case of a stabilized flag already? For example, I see a few mentions to LLVM already in https://doc.rust-lang.org/rustc/codegen-options/index.html#codegen-units (e.g., codegen-units, control-flow-guard, embed-bitcode, etc.). Those all seem to be similar cases that would need to be reimplemented if we replace the default backend so they won't become a breaking change as well.

Given this, I'm not sure whether adding another unstable option to the compiler, and requiring the user to pass an additional option to be able to use the sanitizers is worth it. What do you think?

Yeah, that's fair, I guess if we wanted to change the default for debug builds, we'd have to do a dirty "if -Csanitize, -Cembed-bitcode, --emit=llvm-ir, etc. is set, fall back to using LLVM".

I'll CC @bjorn3 though, just to make absolutely sure that it doesn't conflict with Cranelift's future plans.

@glandium
Copy link
Contributor

-Clinker-plugin-lto is another flag that is specific to LLVM.

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from 8af3b93 to bed8f9c Compare November 16, 2024 09:45
@rustbot rustbot added the A-compiletest Area: The compiletest test runner label Nov 16, 2024
akshayrdeodhar pushed a commit to akshayrdeodhar/llvm-project that referenced this pull request Nov 18, 2024
Full list is quite long, and quality of implementation can
vary.

Drop the lists to avoid confusion like
rust-lang/rust#123617 (comment)

We don't maintain these for other sanitizers.
@rcvalle
Copy link
Member Author

rcvalle commented Nov 19, 2024

Thank you everyone again for the patience and the time while I went through all the issues listed here. Here are the final updates about these issues:

I also added AddressSanitizer for aarch64-apple-darwin since it was promoted to Tier 1 in #128592, but let me know if anyone has any objections. Otherwise, this PR should be ready to be merged.

Thank you to everyone that contributed to and in this PR! Also thank you very much for helping me out with pushing this through the last mile, @tmiasko, @1c3t3a, and @jakos-sec! It was much appreciated.

Comment on lines +554 to +555
For more information on sanitizers, see the
[sanitizer
feature](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/sanitizer.html)
in the [The Rust Unstable
Book](https://doc.rust-lang.org/nightly/unstable-book/). For more information on
Copy link
Member

Choose a reason for hiding this comment

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

I think we should move the relevant documentation for stable sanitizers into this document (we should not need to refer people to the unstable book for information on stable features 🙂)

In particular, the section ASan should be moved and I think it would be extremely helpful to have a section on some of the considerations that need to be taken into account to use sanitizers in mixed C/C++/Rust codebases as well as a general disclaimer that the quality of the sanitizer support varies across platforms and relies heavily on LLVM's implementation.

in the [The Rust Unstable
Book](https://doc.rust-lang.org/nightly/unstable-book/). For more information on
stable and supported sanitizers, see the [supported sanitizers
table](https://github.com/rust-lang/rust/issues/123615#issuecomment-2041791236).
Copy link
Member

Choose a reason for hiding this comment

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

This table should live in this doc as well.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, this table already exists above? I think this sentence can just be removed then?

@@ -104,6 +104,8 @@
// Do not check link redundancy on bootstraping phase
#![allow(rustdoc::redundant_explicit_links)]
#![warn(rustdoc::unescaped_backticks)]
// FIXME: Remove after `no_sanitize` stabilization (along with `#![feature(no_sanitize)]`)
#![allow(stable_features)]
Copy link
Member

Choose a reason for hiding this comment

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

You can change the #![feature(no_sanitize)] below to #![cfg_attr(bootstrap, feature(no_sanitize))] and that will also ensure it is removed once a compiler with the feature stabilized is used for bootstrapping 🙂

@@ -263,6 +263,8 @@
#![deny(ffi_unwind_calls)]
// std may use features in a platform-specific way
#![allow(unused_features)]
// FIXME: Remove after `no_sanitize` stabilization (along with `#![feature(no_sanitize)]`)
#![allow(stable_features)]
Copy link
Member

Choose a reason for hiding this comment

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

Same here


------------------------

The `no_sanitize` attribute can be used to selectively disable sanitizer
Copy link
Member

Choose a reason for hiding this comment

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

This info will need to go into the Reference (probably here? https://github.com/rust-lang/reference/blob/master/src/attributes/codegen.md)

in the [The Rust Unstable
Book](https://doc.rust-lang.org/nightly/unstable-book/). For more information on
stable and supported sanitizers, see the [supported sanitizers
table](https://github.com/rust-lang/rust/issues/123615#issuecomment-2041791236).
Copy link
Member

Choose a reason for hiding this comment

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

Oh, this table already exists above? I think this sentence can just be removed then?

|--------|------------|
| aarch64-unknown-linux-gnu | address, leak |
| i586-pc-windows-msvc | address |
| i586-unknown-linux-gnu | address |
Copy link
Member

Choose a reason for hiding this comment

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

Right?

Suggested change
| i586-unknown-linux-gnu | address |
| i686-unknown-linux-gnu | address |

| Target | Sanitizers |
|--------|------------|
| aarch64-unknown-linux-gnu | address, leak |
| i586-pc-windows-msvc | address |
Copy link
Member

Choose a reason for hiding this comment

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

i586-pc-windows-msvc isn't changed in this PR or a Tier 1 target

Suggested change
| i586-pc-windows-msvc | address |

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from 72102f8 to 01822f2 Compare December 13, 2024 05:17
@rust-log-analyzer

This comment has been minimized.

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from 01822f2 to dae2b7a Compare December 13, 2024 19:33
@rust-log-analyzer

This comment has been minimized.

@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from dae2b7a to 4f14c34 Compare December 13, 2024 20:34
@rust-log-analyzer

This comment has been minimized.

Add suppport for specifying stable sanitizers in addition to the
existing supported sanitizers.
Stabilize AddressSanitizer and LeakSanitizer for the Tier 1 targets that
support them.
Stabilize the `no_sanitize` attribute so stable sanitizers can also be
selectively disabled for annotated functions.
Stabilize AddressSanitizer for aarch64-apple-darwin since it was
promoted to Tier 1 in rust-lang#128592.
@rcvalle rcvalle force-pushed the rust-stabilize-core-sanitizers branch from 4f14c34 to 89d1ada Compare December 16, 2024 21:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-compiletest Area: The compiletest test runner A-run-make Area: port run-make Makefiles to rmake.rs A-testsuite Area: The testsuite used to check the correctness of rustc disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. PG-exploit-mitigations Project group: Exploit mitigations proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-bootstrap Relevant to the bootstrap subteam: Rust's build system (x.py and src/bootstrap) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-infra Relevant to the infrastructure team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.