Skip to content

Commit 9277697

Browse files
committed
Add linux_rustix opt-in backend
1 parent ce35c67 commit 9277697

File tree

7 files changed

+95
-7
lines changed

7 files changed

+95
-7
lines changed

.github/workflows/nopanic.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ jobs:
4040
- name: Check (linux_android.rs)
4141
run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]
4242

43+
# TODO: re-enable after https://github.com/bytecodealliance/rustix/pull/1184 is released
44+
# - name: Build (linux_rustix.rs)
45+
# env:
46+
# RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_rustix"
47+
# run: cargo build --release
48+
# - name: Check (linux_rustix.rs)
49+
# run: ret=$(grep panic target/release/libgetrandom_wrapper.so; echo $?); [ $ret -eq 1 ]
50+
4351
- name: Build (rdrand.rs)
4452
env:
4553
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="rdrand"

.github/workflows/tests.yml

+3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ jobs:
7171
- env:
7272
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"
7373
run: cargo test ${{ matrix.cargo_test_opts }} --target=${{ matrix.target }} --features=std
74+
- env:
75+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_rustix"
76+
run: cargo test ${{ matrix.cargo_test_opts }} --target=${{ matrix.target }} --features=std
7477
- env:
7578
RUSTFLAGS: -Dwarnings --cfg getrandom_test_linux_fallback
7679
run: cargo test --features=std

.github/workflows/workspace.yml

+4
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ jobs:
5353
env:
5454
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_getrandom"
5555
run: cargo clippy --target x86_64-unknown-linux-gnu
56+
- name: Linux (linux_rustix.rs)
57+
env:
58+
RUSTFLAGS: -Dwarnings --cfg getrandom_backend="linux_rustix"
59+
run: cargo clippy --target x86_64-unknown-linux-gnu
5660
- name: Linux (linux_android_with_fallback.rs)
5761
run: cargo clippy --target x86_64-unknown-linux-gnu
5862
- name: NetBSD (netbsd.rs)

CHANGELOG.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2828
- `wasm32-wasip1` and `wasm32-wasip2` support [#499]
2929
- `getrandom_backend` configuration flag for selection of opt-in backends [#504]
3030
- `Error::new_custom` method [#507]
31-
- AArch64 RNDR register opt-in backend [#512]
31+
- `rndr` opt-in backend [#512]
32+
- `linux_rustix` opt-in backend [#520]
3233

3334
[#415]: https://github.com/rust-random/getrandom/pull/415
3435
[#440]: https://github.com/rust-random/getrandom/pull/440
@@ -40,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
4041
[#504]: https://github.com/rust-random/getrandom/pull/504
4142
[#507]: https://github.com/rust-random/getrandom/pull/507
4243
[#512]: https://github.com/rust-random/getrandom/pull/512
44+
[#520]: https://github.com/rust-random/getrandom/pull/520
4345

4446
## [0.2.15] - 2024-05-06
4547
### Added

Cargo.toml

+41-4
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,68 @@ cfg-if = "1"
1818
compiler_builtins = { version = "0.1", optional = true }
1919
core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" }
2020

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

25+
# linux_rustix
26+
[target.'cfg(all(any(target_os = "linux", target_os = "android"), any(target_env = "", getrandom_backend = "linux_rustix")))'.dependencies]
27+
rustix = { version = "0.38", default-features = false, features = ["rand"] }
28+
29+
# apple-other
30+
[target.'cfg(any(target_os = "ios", target_os = "visionos", target_os = "watchos", target_os = "tvos"))'.dependencies]
31+
libc = { version = "0.2.154", default-features = false }
32+
33+
# getentropy
34+
[target.'cfg(any(target_os = "macos", target_os = "openbsd", target_os = "vita", target_os = "emscripten"))'.dependencies]
35+
libc = { version = "0.2.154", default-features = false }
36+
37+
# getrandom
38+
[target.'cfg(any(target_os = "dragonfly", target_os = "freebsd", target_os = "hurd", target_os = "illumos", all(target_os = "horizon", target_arch = "arm")))'.dependencies]
39+
libc = { version = "0.2.154", default-features = false }
40+
41+
# netbsd
42+
[target.'cfg(target_os = "netbsd")'.dependencies]
43+
libc = { version = "0.2.154", default-features = false }
44+
45+
# solaris
46+
[target.'cfg(target_os = "solaris")'.dependencies]
47+
libc = { version = "0.2.154", default-features = false }
48+
49+
# use_file
50+
[target.'cfg(any(target_os = "haiku", target_os = "redox", target_os = "nto", target_os = "aix"))'.dependencies]
51+
libc = { version = "0.2.154", default-features = false }
52+
53+
# vxworks
54+
[target.'cfg(target_os = "vxworks")'.dependencies]
55+
libc = { version = "0.2.154", default-features = false }
56+
57+
# wasi (0.2 only)
2458
[target.'cfg(all(target_arch = "wasm32", target_os = "wasi", target_env = "p2"))'.dependencies]
2559
wasi = { version = "0.13", default-features = false }
2660

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

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

3672
[features]
37-
# Implement std-only traits for getrandom::Error
73+
# Implement std::error::Error for getrandom::Error and
74+
# use std to retrieve OS error descriptions
3875
std = []
3976
# Unstable feature to support being a libstd dependency
4077
rustc-dep-of-std = ["compiler_builtins", "core"]
4178

4279
[lints.rust.unexpected_cfgs]
4380
level = "warn"
4481
check-cfg = [
45-
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "wasm_js", "esp_idf"))',
82+
'cfg(getrandom_backend, values("custom", "rdrand", "rndr", "linux_getrandom", "linux_rustix", "wasm_js", "esp_idf"))',
4683
'cfg(getrandom_browser_test)',
4784
'cfg(getrandom_test_linux_fallback)',
4885
]

src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
//! | ------------------ | ------------------ | --------------
77
//! | Linux, Android | `*‑linux‑*` | [`getrandom`][1] system call if available, otherwise [`/dev/urandom`][2] after successfully polling `/dev/random`
88
//! | Windows 10+ | `*‑windows‑*` | [`ProcessPrng`]
9-
//! | Windows 7 and 8 | `*-win7‑windows‑*` | [`RtlGenRandom`]
9+
//! | Windows 7, 8 | `*-win7‑windows‑*` | [`RtlGenRandom`]
1010
//! | macOS | `*‑apple‑darwin` | [`getentropy`][3]
1111
//! | iOS, tvOS, watchOS | `*‑apple‑ios`, `*-apple-tvos`, `*-apple-watchos` | [`CCRandomGenerateBytes`]
1212
//! | FreeBSD | `*‑freebsd` | [`getrandom`][5]
1313
//! | OpenBSD | `*‑openbsd` | [`getentropy`][7]
1414
//! | NetBSD | `*‑netbsd` | [`getrandom`][16] if available, otherwise [`kern.arandom`][8]
1515
//! | Dragonfly BSD | `*‑dragonfly` | [`getrandom`][9]
16-
//! | Solaris | `*‑solaris` | [`getrandom`][11] (with `GRND_RANDOM`)
16+
//! | Solaris | `*‑solaris` | [`getrandom`][11] with `GRND_RANDOM`
1717
//! | illumos | `*‑illumos` | [`getrandom`][12]
1818
//! | Fuchsia OS | `*‑fuchsia` | [`cprng_draw`]
1919
//! | Redox | `*‑redox` | `/dev/urandom`
@@ -41,6 +41,7 @@
4141
//! | Backend name | Target | Target Triple | Implementation
4242
//! | ----------------- | -------------------- | -------------------- | --------------
4343
//! | `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).
44+
//! | `linux_rustix` | Linux, Android | `*‑linux‑*` | Same as `linux_getrandom`, but uses [`rustix`] instead of `libc`.
4445
//! | `rdrand` | x86, x86-64 | `x86_64-*`, `i686-*` | [`RDRAND`] instruction
4546
//! | `rndr` | AArch64 | `aarch64-*` | [`RNDR`] register
4647
//! | `esp_idf` | ESP-IDF | `*‑espidf` | [`esp_fill_random`]. WARNING: can return low quality entropy without proper hardware configuration!
@@ -243,6 +244,7 @@
243244
//! [platform-support]: https://doc.rust-lang.org/stable/rustc/platform-support.html
244245
//! [WASI]: https://github.com/CraneStation/wasi
245246
//! [Emscripten]: https://www.hellorust.com/setup/emscripten/
247+
//! [`rustix`]: https://docs.rs/rustix
246248
247249
#![doc(
248250
html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
@@ -295,6 +297,8 @@ cfg_if! {
295297
} else if #[cfg(getrandom_backend = "linux_getrandom")] {
296298
mod util_libc;
297299
#[path = "linux_android.rs"] mod imp;
300+
} else if #[cfg(getrandom_backend = "linux_rustix")] {
301+
#[path = "linux_rustix.rs"] mod imp;
298302
} else if #[cfg(getrandom_backend = "rdrand")] {
299303
mod lazy;
300304
#[path = "rdrand.rs"] mod imp;

src/linux_rustix.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! Implementation for Linux / Android without `/dev/urandom` fallback
2+
use crate::{Error, MaybeUninit};
3+
use rustix::rand::{getrandom_uninit, GetRandomFlags};
4+
5+
#[cfg(not(any(target_os = "android", target_os = "linux")))]
6+
compile_error!("`linux_rustix` backend can be enabled only for Linux/Android targets!");
7+
8+
pub fn getrandom_inner(mut dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
9+
loop {
10+
let res = getrandom_uninit(dest, GetRandomFlags::empty()).map(|(res, _)| res.len());
11+
match res {
12+
Ok(0) => return Err(Error::UNEXPECTED),
13+
Ok(res_len) => {
14+
dest = dest.get_mut(res_len..).ok_or(Error::UNEXPECTED)?;
15+
if dest.is_empty() {
16+
return Ok(());
17+
}
18+
}
19+
Err(rustix::io::Errno::INTR) => continue,
20+
Err(err) => {
21+
let code = err
22+
.raw_os_error()
23+
.wrapping_neg()
24+
.try_into()
25+
.map_err(|_| Error::UNEXPECTED)?;
26+
return Err(Error::from_os_error(code));
27+
}
28+
}
29+
}
30+
}

0 commit comments

Comments
 (0)