Skip to content

Commit

Permalink
Merge branch 'master' into release/v0.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov authored Dec 27, 2024
2 parents 4b05b9c + 9b902af commit 2acf955
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 34 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,14 +165,14 @@ jobs:
- name: Build
run: cargo build --target ${{ matrix.target.target }} ${{ matrix.feature.feature }} -Zbuild-std=${{ matrix.feature.build-std }}

rdrand:
name: RDRAND
rdrand-uefi:
name: RDRAND UEFI
runs-on: ubuntu-24.04
strategy:
matrix:
target: [
x86_64-unknown-uefi,
x86_64-unknown-l4re-uclibc,
i686-unknown-uefi,
]
steps:
- uses: actions/checkout@v4
Expand All @@ -183,6 +183,9 @@ jobs:
- env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="rdrand"
run: cargo build -Z build-std=core --target=${{ matrix.target }}
- env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="rdrand"
run: cargo build -Z build-std=std --target=${{ matrix.target }} --features std

rndr:
name: RNDR
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ jobs:
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
RUSTFLAGS: -Dwarnings -Zsanitizer=memory
RUSTDOCFLAGS: -Dwarnings -Zsanitizer=memory
run: cargo test -Zbuild-std --target=x86_64-unknown-linux-gnu

cross:
name: Cross
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,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]
- Automatic MemorySanitizer support [#521] [#571]
- `u32` and `u64` functions for generating random values of the respective type [#544]
- `wasm32v1-none` support in the `wasm_js` backend [#560]

Expand Down Expand Up @@ -67,6 +67,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#559]: https://github.com/rust-random/getrandom/pull/559
[#560]: https://github.com/rust-random/getrandom/pull/560
[#562]: https://github.com/rust-random/getrandom/pull/562
[#571]: https://github.com/rust-random/getrandom/pull/571

## [0.2.15] - 2024-05-06
### Added
Expand Down
5 changes: 2 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,19 @@ wasm-bindgen-test = "0.3"
# use std to retrieve OS error descriptions
std = []
# Unstable feature to support being a libstd dependency
rustc-dep-of-std = ["compiler_builtins", "core"]
rustc-dep-of-std = ["dep:compiler_builtins", "dep:core"]

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "linux_rustix", "wasm_js", "esp_idf"))',
'cfg(getrandom_sanitize)',
'cfg(getrandom_msan)',
'cfg(getrandom_test_linux_fallback)',
'cfg(getrandom_test_netbsd_fallback)',
]

[package.metadata.docs.rs]
features = ["std"]
rustdoc-args = ["--cfg", "docsrs"]

# workaround for https://github.com/cross-rs/cross/issues/1345
[package.metadata.cross.target.x86_64-unknown-netbsd]
Expand Down
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,15 +267,14 @@ our code should correctly handle it and return an error, e.g.

## Sanitizer support

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

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

## Minimum Supported Rust Version
Expand Down
9 changes: 9 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Automatically detect cfg(sanitize = "memory") even if cfg(sanitize) isn't
// supported. Build scripts get cfg() info, even if the cfg is unstable.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let santizers = std::env::var("CARGO_CFG_SANITIZE").unwrap_or_default();
if santizers.contains("memory") {
println!("cargo:rustc-cfg=getrandom_msan");
}
}
2 changes: 1 addition & 1 deletion src/backends/rdrand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ unsafe fn rdrand_u32() -> Option<u32> {
unsafe fn rdrand_u64() -> Option<u64> {
let a = rdrand()?;
let b = rdrand()?;
Some((u64::from(a) << 32) || u64::from(b))
Some((u64::from(a) << 32) | u64::from(b))
}

pub fn inner_u32() -> Result<u32, Error> {
Expand Down
37 changes: 26 additions & 11 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@ extern crate std;

use core::{fmt, num::NonZeroU32};

// This private alias mirrors `std::io::RawOsError`:
// https://doc.rust-lang.org/std/io/type.RawOsError.html)
cfg_if::cfg_if!(
if #[cfg(target_os = "uefi")] {
type RawOsError = usize;
} else {
type RawOsError = i32;
}
);

/// A small and `no_std` compatible error type
///
/// The [`Error::raw_os_error()`] will indicate if the error is from the OS, and
Expand Down Expand Up @@ -57,20 +67,25 @@ impl Error {
/// Extract the raw OS error code (if this error came from the OS)
///
/// This method is identical to [`std::io::Error::raw_os_error()`][1], except
/// that it works in `no_std` contexts. If this method returns `None`, the
/// error value can still be formatted via the `Display` implementation.
/// that it works in `no_std` contexts. On most targets this method returns
/// `Option<i32>`, but some platforms (e.g. UEFI) may use a different primitive
/// type like `usize`. Consult with the [`RawOsError`] docs for more information.
///
/// If this method returns `None`, the error value can still be formatted via
/// the `Display` implementation.
///
/// [1]: https://doc.rust-lang.org/std/io/struct.Error.html#method.raw_os_error
/// [`RawOsError`]: https://doc.rust-lang.org/std/io/type.RawOsError.html
#[inline]
pub fn raw_os_error(self) -> Option<i32> {
i32::try_from(self.0.get()).ok().map(|errno| {
// On SOLID, negate the error code again to obtain the original error code.
if cfg!(target_os = "solid_asp3") {
-errno
} else {
errno
}
})
pub fn raw_os_error(self) -> Option<RawOsError> {
let code = self.0.get();
if code >= Self::INTERNAL_START {
return None;
}
let errno = RawOsError::try_from(code).ok()?;
#[cfg(target_os = "solid_asp3")]
let errno = -errno;
Some(errno)
}

/// Creates a new instance of an `Error` from a particular custom error code.
Expand Down
7 changes: 2 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#![doc = include_str!("../README.md")]
#![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,
Expand Down Expand Up @@ -99,17 +98,15 @@ pub fn fill_uninit(dest: &mut [MaybeUninit<u8>]) -> Result<&mut [u8], Error> {
backends::fill_inner(dest)?;
}

#[cfg(getrandom_sanitize)]
#[cfg(sanitize = "memory")]
#[cfg(getrandom_msan)]
extern "C" {
fn __msan_unpoison(a: *mut core::ffi::c_void, size: usize);
}

// SAFETY: `dest` has been fully initialized by `imp::fill_inner`
// since it returned `Ok`.
Ok(unsafe {
#[cfg(getrandom_sanitize)]
#[cfg(sanitize = "memory")]
#[cfg(getrandom_msan)]
__msan_unpoison(dest.as_mut_ptr().cast(), dest.len());

util::slice_assume_init_mut(dest)
Expand Down

0 comments on commit 2acf955

Please sign in to comment.