From ccb9b04e14fdae9ec7ce1da94e5edc1520282aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 16 Oct 2024 09:13:16 +0300 Subject: [PATCH 1/3] Add memory sanitizer support --- .github/workflows/tests.yml | 14 ++++++++++++++ Cargo.toml | 1 + src/lib.rs | 27 ++++++++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d02dcdb8..1f1c320f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -159,6 +159,20 @@ jobs: - run: cargo test --target=x86_64-win7-windows-msvc -Z build-std --features=std - run: cargo test --target=i686-win7-windows-msvc -Z build-std --features=std + sanitizer-test: + name: Sanitizer Test + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly-2024-10-08 + components: rust-src + - env: + RUSTFLAGS: -Dwarnings -Zsanitizer=memory --cfg getrandom_sanitize + # `--all-targets` is used to skip doc tests which currently fail linking + run: cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu --all-targets + cross-tests: name: Cross Test runs-on: ubuntu-22.04 diff --git a/Cargo.toml b/Cargo.toml index b2fb74ef..01bd81f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -80,6 +80,7 @@ rustc-dep-of-std = ["compiler_builtins", "core"] level = "warn" check-cfg = [ 'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "linux_rustix", "wasm_js", "esp_idf"))', + 'cfg(getrandom_sanitize)', 'cfg(getrandom_browser_test)', 'cfg(getrandom_test_linux_fallback)', ] diff --git a/src/lib.rs b/src/lib.rs index d0e84c7a..441b74f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -205,6 +205,17 @@ //! result, our code should correctly handle it and return an error like //! [`Error::UNEXPECTED`]. //! +//! ## Sanitizer support +//! +//! If your code uses `getrandom_uninit` and you use memory sanitizer +//! (i.e. `-Zsanitizer=memory`), then you need to pass `getrandom_sanitize` +//! configuration flag for `getrandom_uninit` to unpoison destination buffer. +//! +//! For example, it can be done like this (requires Nightly compiler): +//! ``` +//! RUSTFLAGS="-Zsanitizer=memory --cfg getrandom_sanitize" cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu +//! ``` +//! //! [1]: https://manned.org/getrandom.2 //! [2]: https://manned.org/urandom.4 //! [3]: https://www.unix.com/man-page/mojave/2/getentropy/ @@ -254,6 +265,7 @@ #![no_std] #![warn(rust_2018_idioms, unused_lifetimes, missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![cfg_attr(getrandom_sanitize, feature(cfg_sanitize))] #![deny( clippy::cast_lossless, clippy::cast_possible_truncation, @@ -474,7 +486,20 @@ pub fn getrandom_uninit(dest: &mut [MaybeUninit]) -> Result<&mut [u8], Error if !dest.is_empty() { imp::getrandom_inner(dest)?; } + + #[cfg(getrandom_sanitize)] + #[cfg(sanitize = "memory")] + extern "C" { + fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize); + } + // SAFETY: `dest` has been fully initialized by `imp::getrandom_inner` // since it returned `Ok`. - Ok(unsafe { slice_assume_init_mut(dest) }) + Ok(unsafe { + #[cfg(getrandom_sanitize)] + #[cfg(sanitize = "memory")] + __msan_unpoison(dest.as_mut_ptr().cast(), dest.len()); + + slice_assume_init_mut(dest) + }) } From aab78f49467de8f307d6c9b950501aa29ba02f1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 16 Oct 2024 09:15:30 +0300 Subject: [PATCH 2/3] fix doctest --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 441b74f4..7c3cec23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -212,7 +212,7 @@ //! configuration flag for `getrandom_uninit` to unpoison destination buffer. //! //! For example, it can be done like this (requires Nightly compiler): -//! ``` +//! ```text //! RUSTFLAGS="-Zsanitizer=memory --cfg getrandom_sanitize" cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu //! ``` //! From db88d717a62fbca22c38609518e8f63dde41007d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 16 Oct 2024 09:16:43 +0300 Subject: [PATCH 3/3] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f63dc37f..74971dbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Error::new_custom` method [#507] - `rndr` opt-in backend [#512] - `linux_rustix` opt-in backend [#520] +- Memory sanitizer support gated behind `getrandom_sanitize` configuration flag [#521] [#415]: https://github.com/rust-random/getrandom/pull/415 [#440]: https://github.com/rust-random/getrandom/pull/440 @@ -42,6 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 [#507]: https://github.com/rust-random/getrandom/pull/507 [#512]: https://github.com/rust-random/getrandom/pull/512 [#520]: https://github.com/rust-random/getrandom/pull/520 +[#521]: https://github.com/rust-random/getrandom/pull/521 ## [0.2.15] - 2024-05-06 ### Added