Skip to content

Commit

Permalink
Add linux_rustix opt-in backend
Browse files Browse the repository at this point in the history
  • Loading branch information
newpavlov committed Oct 16, 2024
1 parent ce35c67 commit 9277697
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 7 deletions.
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));
}
}
}
}

0 comments on commit 9277697

Please sign in to comment.