Skip to content

Commit 9b902af

Browse files
authored
Detect use of MemorySanitizer without using Nightly-only features (#571)
This allows msan detection to "just-work" whenever someone passes `-Zsanitizer=memory`. Users no longer need to do any `getrandom`-specific configuration. This will also continue working once rust-lang/rust#123615 is merged, which stabilizes some sanitizers (but not MemorySanitizer). This is the approch taken by other low-level crates: - [`parking_lot_core`](https://github.com/Amanieu/parking_lot/blob/ca920b31312839013b4455aba1d53a4aede21b2f/core/build.rs) - [`crossbeam-utils`](https://github.com/crossbeam-rs/crossbeam/blob/00283fb1818174c25b02d7f1c883c5e19f8506a4/crossbeam-utils/build.rs#L42) The only downside is that this adds a build-script, but it's as small as possible, doesn't seem to impact build times, and is only a temporary workaround. --------- Signed-off-by: Joe Richey <[email protected]>
1 parent dc89211 commit 9b902af

File tree

6 files changed

+23
-17
lines changed

6 files changed

+23
-17
lines changed

Diff for: .github/workflows/tests.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ jobs:
140140
toolchain: nightly-2024-10-08
141141
components: rust-src
142142
- env:
143-
RUSTFLAGS: -Dwarnings -Zsanitizer=memory --cfg getrandom_sanitize
144-
# `--all-targets` is used to skip doc tests which currently fail linking
145-
run: cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu --all-targets
143+
RUSTFLAGS: -Dwarnings -Zsanitizer=memory
144+
RUSTDOCFLAGS: -Dwarnings -Zsanitizer=memory
145+
run: cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu
146146

147147
cross:
148148
name: Cross

Diff for: CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3737
- `Error::new_custom` method [#507]
3838
- `rndr` opt-in backend [#512]
3939
- `linux_rustix` opt-in backend [#520]
40-
- Memory sanitizer support gated behind `getrandom_sanitize` configuration flag [#521]
40+
- Automatic MemorySanitizer support [#521] [#571]
4141
- `u32` and `u64` functions for generating random values of the respective type [#544]
4242

4343
### Fixed
@@ -61,6 +61,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6161
[#554]: https://github.com/rust-random/getrandom/pull/554
6262
[#555]: https://github.com/rust-random/getrandom/pull/555
6363
[#557]: https://github.com/rust-random/getrandom/pull/557
64+
[#571]: https://github.com/rust-random/getrandom/pull/571
6465

6566
## [0.2.15] - 2024-05-06
6667
### Added

Diff for: Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ rustc-dep-of-std = ["dep:compiler_builtins", "dep:core"]
8181
level = "warn"
8282
check-cfg = [
8383
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "linux_rustix", "wasm_js", "esp_idf"))',
84-
'cfg(getrandom_sanitize)',
84+
'cfg(getrandom_msan)',
8585
'cfg(getrandom_test_linux_fallback)',
8686
'cfg(getrandom_test_netbsd_fallback)',
8787
]

Diff for: README.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -267,15 +267,14 @@ our code should correctly handle it and return an error, e.g.
267267

268268
## Sanitizer support
269269

270-
If your code uses [`fill_uninit`] and you enable memory sanitization
271-
(i.e. `-Zsanitizer=memory`), you need to pass the `getrandom_sanitize`
272-
configuration flag to enable unpoisoning of the destination buffer
273-
filled by `fill_uninit`.
270+
If your code uses [`fill_uninit`] and you enable
271+
[MemorySanitizer](https://doc.rust-lang.org/beta/unstable-book/compiler-flags/sanitizer.html#memorysanitizer)
272+
(i.e. `-Zsanitizer=memory`), we will automatically handle unpoisoning
273+
of the destination buffer filled by `fill_uninit`.
274274

275-
For example, it can be done as follows (requires a Nightly compiler):
275+
You can run sanitizer tests for your crate dependent on `getrandom` like this:
276276
```sh
277-
RUSTFLAGS="-Zsanitizer=memory --cfg getrandom_sanitize" \
278-
cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu
277+
RUSTFLAGS="-Zsanitizer=memory" cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu
279278
```
280279

281280
## Minimum Supported Rust Version

Diff for: build.rs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
2+
// supported. Build scripts get cfg() info, even if the cfg is unstable.
3+
fn main() {
4+
println!("cargo:rerun-if-changed=build.rs");
5+
let santizers = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default();
6+
if santizers.contains("memory") {
7+
println!("cargo:rustc-cfg=getrandom_msan");
8+
}
9+
}

Diff for: src/lib.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#![doc = include_str!("../README.md")]
1111
#![warn(rust_2018_idioms, unused_lifetimes, missing_docs)]
1212
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
13-
#![cfg_attr(getrandom_sanitize, feature(cfg_sanitize))]
1413
#![deny(
1514
clippy::cast_lossless,
1615
clippy::cast_possible_truncation,
@@ -99,17 +98,15 @@ pub fn fill_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
9998
backends::fill_inner(dest)?;
10099
}
101100

102-
#[cfg(getrandom_sanitize)]
103-
#[cfg(sanitize = "memory")]
101+
#[cfg(getrandom_msan)]
104102
extern "C" {
105103
fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize);
106104
}
107105

108106
// SAFETY: `dest` has been fully initialized by `imp::fill_inner`
109107
// since it returned `Ok`.
110108
Ok(unsafe {
111-
#[cfg(getrandom_sanitize)]
112-
#[cfg(sanitize = "memory")]
109+
#[cfg(getrandom_msan)]
113110
__msan_unpoison(dest.as_mut_ptr().cast(), dest.len());
114111

115112
util::slice_assume_init_mut(dest)

0 commit comments

Comments
 (0)