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

Add linux_rustix opt-in backend #520

Merged
merged 1 commit into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/nopanic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ jobs:
- name: Check (linux_android.rs)
run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]

# TODO: re-enable after https://github.com/bytecodealliance/rustix/pull/1184 is released
# - name: Build (linux_rustix.rs)
# env:
# RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_rustix"
# run: cargo build --release
# - name: Check (linux_rustix.rs)
# run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]

- name: Build (rdrand.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="rdrand"
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ jobs:
- env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"
run: cargo test ${{ matrix.cargo_test_opts }} --target=${{ matrix.target }} --features=std
- env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_rustix"
run: cargo test ${{ matrix.cargo_test_opts }} --target=${{ matrix.target }} --features=std
- env:
RUSTFLAGS: -Dwarnings --cfg getrandom_test_linux_fallback
run: cargo test --features=std
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/workspace.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ jobs:
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"
run: cargo clippy --target x86_64-unknown-linux-gnu
- name: Linux (linux_rustix.rs)
env:
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_rustix"
run: cargo clippy --target x86_64-unknown-linux-gnu
- name: Linux (linux_android_with_fallback.rs)
run: cargo clippy --target x86_64-unknown-linux-gnu
- name: NetBSD (netbsd.rs)
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `wasm32-wasip1` and `wasm32-wasip2` support [#499]
- `getrandom_backend` configuration flag for selection of opt-in backends [#504]
- `Error::new_custom` method [#507]
- AArch64 RNDR register opt-in backend [#512]
- `rndr` opt-in backend [#512]
- `linux_rustix` opt-in backend [#520]

[#415]: https://github.com/rust-random/getrandom/pull/415
[#440]: https://github.com/rust-random/getrandom/pull/440
Expand All @@ -40,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[#504]: https://github.com/rust-random/getrandom/pull/504
[#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

## [0.2.15] - 2024-05-06
### Added
Expand Down
45 changes: 41 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,68 @@ cfg-if = "1"
compiler_builtins = { version = "0.1", optional = true }
core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" }

[target.'cfg(unix)'.dependencies]
# linux_android / linux_android_with_fallback
[target.'cfg(all(any(target_os = "linux", target_os = "android"), not(any(target_env = "", getrandom_backend = "linux_rustix", getrandom_backend = "custom"))))'.dependencies]
libc = { version = "0.2.154", default-features = false }

# linux_rustix
[target.'cfg(all(any(target_os = "linux", target_os = "android"), any(target_env = "", getrandom_backend = "linux_rustix")))'.dependencies]
rustix = { version = "0.38", default-features = false, features = ["rand"] }

# apple-other
[target.'cfg(any(target_os = "ios", target_os = "visionos", target_os = "watchos", target_os = "tvos"))'.dependencies]
libc = { version = "0.2.154", default-features = false }

# getentropy
[target.'cfg(any(target_os = "macos", target_os = "openbsd", target_os = "vita", target_os = "emscripten"))'.dependencies]
libc = { version = "0.2.154", default-features = false }

# getrandom
[target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", target_os = "illumos", all(target_os = "horizon", target_arch = "arm")))'.dependencies]
libc = { version = "0.2.154", default-features = false }

# netbsd
[target.'cfg(target_os = "netbsd")'.dependencies]
libc = { version = "0.2.154", default-features = false }

# solaris
[target.'cfg(target_os = "solaris")'.dependencies]
libc = { version = "0.2.154", default-features = false }

# use_file
[target.'cfg(any(target_os = "haiku", target_os = "redox", target_os = "nto", target_os = "aix"))'.dependencies]
libc = { version = "0.2.154", default-features = false }

# vxworks
[target.'cfg(target_os = "vxworks")'.dependencies]
libc = { version = "0.2.154", default-features = false }

# wasi (0.2 only)
[target.'cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))'.dependencies]
wasi = { version = "0.13", default-features = false }

# windows7
[target.'cfg(all(windows, not(target_vendor = "win7")))'.dependencies]
windows-targets = "0.52"

# wasm_js
[target.'cfg(all(getrandom_backend = "wasm_js", any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dependencies]
wasm-bindgen = { version = "0.2.89", default-features = false }
js-sys = "0.3"
[target.'cfg(all(getrandom_backend = "wasm_js", getrandom_browser_test, any(target_arch = "wasm32", target_arch = "wasm64"), target_os = "unknown"))'.dev-dependencies]
[target.'cfg(all(getrandom_backend = "wasm_js", getrandom_browser_test, target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies]
wasm-bindgen-test = "0.3.39"

[features]
# Implement std-only traits for getrandom::Error
# Implement std::error::Error for getrandom::Error and
# use std to retrieve OS error descriptions
std = []
# Unstable feature to support being a libstd dependency
rustc-dep-of-std = ["compiler_builtins", "core"]

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js", "esp_idf"))',
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "linux_rustix", "wasm_js", "esp_idf"))',
'cfg(getrandom_browser_test)',
'cfg(getrandom_test_linux_fallback)',
]
Expand Down
8 changes: 6 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
//! | ------------------ | ------------------ | --------------
//! | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
//! | Windows 10+ | `*‑windows‑*` | [`ProcessPrng`]
//! | Windows 7 and 8 | `*-win7‑windows‑*` | [`RtlGenRandom`]
//! | Windows 7, 8 | `*-win7‑windows‑*` | [`RtlGenRandom`]
//! | macOS | `*‑apple‑darwin` | [`getentropy`][3]
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`CCRandomGenerateBytes`]
//! | FreeBSD | `*‑freebsd` | [`getrandom`][5]
//! | OpenBSD | `*‑openbsd` | [`getentropy`][7]
//! | NetBSD | `*‑netbsd` | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]
//! | Dragonfly BSD | `*‑dragonfly` | [`getrandom`][9]
//! | Solaris | `*‑solaris` | [`getrandom`][11] (with `GRND_RANDOM`)
//! | Solaris | `*‑solaris` | [`getrandom`][11] with `GRND_RANDOM`
//! | illumos | `*‑illumos` | [`getrandom`][12]
//! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`]
//! | Redox | `*‑redox` | `/dev/urandom`
Expand Down Expand Up @@ -41,6 +41,7 @@
//! | Backend name | Target | Target Triple | Implementation
//! | ----------------- | -------------------- | -------------------- | --------------
//! | `linux_getrandom` | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call (without `/dev/urandom` fallback). Bumps minimum supported Linux kernel version to 3.17 and Android API level to 23 (Marshmallow).
//! | `linux_rustix` | Linux, Android | `*‑linux‑*` | Same as `linux_getrandom`, but uses [`rustix`] instead of `libc`.
//! | `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction
//! | `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register
//! | `esp_idf` | ESP-IDF | `*‑espidf` | [`esp_fill_random`]. WARNING: can return low quality entropy without proper hardware configuration!
Expand Down Expand Up @@ -243,6 +244,7 @@
//! [platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html
//! [WASI]: https://github.com/CraneStation/wasi
//! [Emscripten]: https://www.hellorust.com/setup/emscripten/
//! [`rustix`]: https://docs.rs/rustix

#![doc(
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
Expand Down Expand Up @@ -295,6 +297,8 @@ cfg_if! {
} else if #[cfg(getrandom_backend = "linux_getrandom")] {
mod util_libc;
#[path = "linux_android.rs"] mod imp;
} else if #[cfg(getrandom_backend = "linux_rustix")] {
#[path = "linux_rustix.rs"] mod imp;
} else if #[cfg(getrandom_backend = "rdrand")] {
mod lazy;
#[path = "rdrand.rs"] mod imp;
Expand Down
30 changes: 30 additions & 0 deletions src/linux_rustix.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Implementation for Linux / Android without `/dev/urandom` fallback
use crate::{Error, MaybeUninit};
use rustix::rand::{getrandom_uninit, GetRandomFlags};

#[cfg(not(any(target_os = "android", target_os = "linux")))]
compile_error!("`linux_rustix` backend can be enabled only for Linux/Android targets!");

pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
loop {
let res = getrandom_uninit(dest, GetRandomFlags::empty()).map(|(res, _)| res.len());
match res {
Ok(0) => return Err(Error::UNEXPECTED),
Ok(res_len) => {
dest = dest.get_mut(res_len..).ok_or(Error::UNEXPECTED)?;
if dest.is_empty() {
return Ok(());
}
}
Err(rustix::io::Errno::INTR) => continue,
Err(err) => {
let code = err
.raw_os_error()
.wrapping_neg()
.try_into()
.map_err(|_| Error::UNEXPECTED)?;
return Err(Error::from_os_error(code));
}
}
}
}
Loading