From 0bfe592f0e80c3c6575e4aebed11c19ce9aeb715 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 28 Oct 2024 19:05:27 +0300 Subject: [PATCH] Move backend implementations to `src/backends/` (#538) This makes it easier to get list of existing backends. It also makes lib.rs and the backends `cfg_if` a bit less cluttered. --- src/backends.rs | 152 ++++++++++++++++++ .../apple_other.rs} | 0 src/{ => backends}/custom.rs | 0 src/{ => backends}/esp_idf.rs | 0 src/{ => backends}/fuchsia.rs | 0 src/{ => backends}/getentropy.rs | 7 +- src/{ => backends}/getrandom.rs | 7 +- src/{ => backends}/hermit.rs | 0 src/{ => backends}/linux_android.rs | 5 +- .../linux_android_with_fallback.rs | 4 +- src/{ => backends}/linux_rustix.rs | 0 src/{ => backends}/netbsd.rs | 7 +- src/{ => backends}/rdrand.rs | 7 +- src/{ => backends}/rndr.rs | 4 +- src/{ => backends}/solaris.rs | 12 +- src/{ => backends}/solid.rs | 0 src/{ => backends}/use_file.rs | 14 +- src/{ => backends}/vxworks.rs | 7 +- src/{ => backends}/wasi.rs | 0 src/{ => backends}/wasm_js.rs | 2 +- src/{ => backends}/windows.rs | 0 src/{ => backends}/windows7.rs | 0 src/{error_impls.rs => error_std_impls.rs} | 0 src/lib.rs | 150 +---------------- 24 files changed, 208 insertions(+), 170 deletions(-) create mode 100644 src/backends.rs rename src/{apple-other.rs => backends/apple_other.rs} (100%) rename src/{ => backends}/custom.rs (100%) rename src/{ => backends}/esp_idf.rs (100%) rename src/{ => backends}/fuchsia.rs (100%) rename src/{ => backends}/getentropy.rs (82%) rename src/{ => backends}/getrandom.rs (88%) rename src/{ => backends}/hermit.rs (100%) rename src/{ => backends}/linux_android.rs (87%) rename src/{ => backends}/linux_android_with_fallback.rs (98%) rename src/{ => backends}/linux_rustix.rs (100%) rename src/{ => backends}/netbsd.rs (95%) rename src/{ => backends}/rdrand.rs (96%) rename src/{ => backends}/rndr.rs (97%) rename src/{ => backends}/solaris.rs (83%) rename src/{ => backends}/solid.rs (100%) rename src/{ => backends}/use_file.rs (97%) rename src/{ => backends}/vxworks.rs (91%) rename src/{ => backends}/wasi.rs (100%) rename src/{ => backends}/wasm_js.rs (98%) rename src/{ => backends}/windows.rs (100%) rename src/{ => backends}/windows7.rs (100%) rename src/{error_impls.rs => error_std_impls.rs} (100%) diff --git a/src/backends.rs b/src/backends.rs new file mode 100644 index 00000000..7ed94cf3 --- /dev/null +++ b/src/backends.rs @@ -0,0 +1,152 @@ +//! System-specific implementations. +//! +//! This module should provide `fill_inner` with the signature +//! `fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error>`. +//! The function MUST fully initialize `dest` when `Ok(())` is returned. +//! The function MUST NOT ever write uninitialized bytes into `dest`, +//! regardless of what value it returns. + +cfg_if! { + if #[cfg(getrandom_backend = "custom")] { + mod custom; + pub use custom::*; + } else if #[cfg(getrandom_backend = "linux_getrandom")] { + mod linux_android; + pub use linux_android::*; + } else if #[cfg(getrandom_backend = "linux_rustix")] { + mod linux_rustix; + pub use linux_rustix::*; + } else if #[cfg(getrandom_backend = "rdrand")] { + mod rdrand; + pub use rdrand::*; + } else if #[cfg(getrandom_backend = "rndr")] { + mod rndr; + pub use rndr::*; + } else if #[cfg(getrandom_backend = "wasm_js")] { + mod wasm_js; + pub use wasm_js::*; + } else if #[cfg(getrandom_backend = "esp_idf")] { + mod esp_idf; + pub use esp_idf::*; + } else if #[cfg(any( + target_os = "haiku", + target_os = "redox", + target_os = "nto", + target_os = "aix", + ))] { + mod use_file; + pub use use_file::*; + } else if #[cfg(any( + target_os = "macos", + target_os = "openbsd", + target_os = "vita", + target_os = "emscripten", + ))] { + mod getentropy; + pub use getentropy::*; + } else if #[cfg(any( + target_os = "dragonfly", + target_os = "freebsd", + target_os = "hurd", + target_os = "illumos", + // Check for target_arch = "arm" to only include the 3DS. Does not + // include the Nintendo Switch (which is target_arch = "aarch64"). + all(target_os = "horizon", target_arch = "arm"), + ))] { + mod getrandom; + pub use getrandom::*; + } else if #[cfg(any( + // Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets + // level 21 (Lollipop) [1], while `getrandom(2)` was added only in + // level 23 (Marshmallow). Note that it applies only to the "old" `target_arch`es, + // RISC-V Android targets sufficiently new API level, same will apply for potential + // new Android `target_arch`es. + // [0]: https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html + // [1]: https://github.com/rust-lang/rust/pull/120593 + all( + target_os = "android", + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "x86", + target_arch = "x86_64", + ), + ), + // Only on these `target_arch`es Rust supports Linux kernel versions (3.2+) + // that precede the version (3.17) in which `getrandom(2)` was added: + // https://doc.rust-lang.org/stable/rustc/platform-support.html + all( + target_os = "linux", + any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "powerpc64", + target_arch = "s390x", + target_arch = "x86", + target_arch = "x86_64", + // Minimum supported Linux kernel version for MUSL targets + // is not specified explicitly (as of Rust 1.77) and they + // are used in practice to target pre-3.17 kernels. + target_env = "musl", + ), + ) + ))] { + mod use_file; + mod linux_android_with_fallback; + pub use linux_android_with_fallback::*; + } else if #[cfg(any(target_os = "android", target_os = "linux"))] { + mod linux_android; + pub use linux_android::*; + } else if #[cfg(target_os = "solaris")] { + mod solaris; + pub use solaris::*; + } else if #[cfg(target_os = "netbsd")] { + mod netbsd; + pub use netbsd::*; + } else if #[cfg(target_os = "fuchsia")] { + mod fuchsia; + pub use fuchsia::*; + } else if #[cfg(any( + target_os = "ios", + target_os = "visionos", + target_os = "watchos", + target_os = "tvos", + ))] { + mod apple_other; + pub use apple_other::*; + } else if #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] { + mod wasi; + pub use wasi::*; + } else if #[cfg(target_os = "hermit")] { + mod hermit; + pub use hermit::*; + } else if #[cfg(target_os = "vxworks")] { + mod vxworks; + pub use vxworks::*; + } else if #[cfg(target_os = "solid_asp3")] { + mod solid; + pub use solid::*; + } else if #[cfg(all(windows, target_vendor = "win7"))] { + mod windows7; + pub use windows7::*; + } else if #[cfg(windows)] { + mod windows; + pub use windows::*; + } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] { + mod rdrand; + pub use rdrand::*; + } else if #[cfg(all( + any(target_arch = "wasm32", target_arch = "wasm64"), + target_os = "unknown", + ))] { + compile_error!("the wasm*-unknown-unknown targets are not supported by \ + default, you may need to enable the \"wasm_js\" \ + configuration flag. For more information see: \ + https://docs.rs/getrandom/#webassembly-support"); + } else { + compile_error!("target is not supported. You may need to define \ + a custom backend see: \ + https://docs.rs/getrandom/#custom-backends"); + } +} diff --git a/src/apple-other.rs b/src/backends/apple_other.rs similarity index 100% rename from src/apple-other.rs rename to src/backends/apple_other.rs diff --git a/src/custom.rs b/src/backends/custom.rs similarity index 100% rename from src/custom.rs rename to src/backends/custom.rs diff --git a/src/esp_idf.rs b/src/backends/esp_idf.rs similarity index 100% rename from src/esp_idf.rs rename to src/backends/esp_idf.rs diff --git a/src/fuchsia.rs b/src/backends/fuchsia.rs similarity index 100% rename from src/fuchsia.rs rename to src/backends/fuchsia.rs diff --git a/src/getentropy.rs b/src/backends/getentropy.rs similarity index 82% rename from src/getentropy.rs rename to src/backends/getentropy.rs index 78c797e1..c93c6ccf 100644 --- a/src/getentropy.rs +++ b/src/backends/getentropy.rs @@ -7,14 +7,17 @@ //! - vita newlib since Dec 2021 //! //! For these targets, we use getentropy(2) because getrandom(2) doesn't exist. -use crate::{util_libc::last_os_error, Error}; +use crate::Error; use core::{ffi::c_void, mem::MaybeUninit}; +#[path = "../util_libc.rs"] +mod util_libc; + pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { for chunk in dest.chunks_mut(256) { let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::(), chunk.len()) }; if ret != 0 { - return Err(last_os_error()); + return Err(util_libc::last_os_error()); } } Ok(()) diff --git a/src/getrandom.rs b/src/backends/getrandom.rs similarity index 88% rename from src/getrandom.rs rename to src/backends/getrandom.rs index e0f463de..298059c2 100644 --- a/src/getrandom.rs +++ b/src/backends/getrandom.rs @@ -15,11 +15,14 @@ //! GRND_RANDOM is not recommended. On NetBSD/FreeBSD/Dragonfly/3ds, it does //! nothing. On illumos, the default pool is used to implement getentropy(2), //! so we assume it is acceptable here. -use crate::{util_libc::sys_fill_exact, Error}; +use crate::Error; use core::{ffi::c_void, mem::MaybeUninit}; +#[path = "../util_libc.rs"] +mod util_libc; + pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - sys_fill_exact(dest, |buf| unsafe { + util_libc::sys_fill_exact(dest, |buf| unsafe { libc::getrandom(buf.as_mut_ptr().cast::(), buf.len(), 0) }) } diff --git a/src/hermit.rs b/src/backends/hermit.rs similarity index 100% rename from src/hermit.rs rename to src/backends/hermit.rs diff --git a/src/linux_android.rs b/src/backends/linux_android.rs similarity index 87% rename from src/linux_android.rs rename to src/backends/linux_android.rs index a4dd4e26..cc59b0b1 100644 --- a/src/linux_android.rs +++ b/src/backends/linux_android.rs @@ -1,7 +1,10 @@ //! Implementation for Linux / Android without `/dev/urandom` fallback -use crate::{util_libc, Error}; +use crate::Error; use core::mem::MaybeUninit; +#[path = "../util_libc.rs"] +mod util_libc; + #[cfg(not(any(target_os = "android", target_os = "linux")))] compile_error!("`linux_getrandom` backend can be enabled only for Linux/Android targets!"); diff --git a/src/linux_android_with_fallback.rs b/src/backends/linux_android_with_fallback.rs similarity index 98% rename from src/linux_android_with_fallback.rs rename to src/backends/linux_android_with_fallback.rs index 53570d2f..4e3ea98c 100644 --- a/src/linux_android_with_fallback.rs +++ b/src/backends/linux_android_with_fallback.rs @@ -1,11 +1,13 @@ //! Implementation for Linux / Android with `/dev/urandom` fallback -use crate::{use_file, util_libc, Error}; +use super::use_file; +use crate::Error; use core::{ ffi::c_void, mem::{self, MaybeUninit}, ptr::{self, NonNull}, sync::atomic::{AtomicPtr, Ordering}, }; +use use_file::util_libc; type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint) -> libc::ssize_t; diff --git a/src/linux_rustix.rs b/src/backends/linux_rustix.rs similarity index 100% rename from src/linux_rustix.rs rename to src/backends/linux_rustix.rs diff --git a/src/netbsd.rs b/src/backends/netbsd.rs similarity index 95% rename from src/netbsd.rs rename to src/backends/netbsd.rs index a96d353f..ddb69736 100644 --- a/src/netbsd.rs +++ b/src/backends/netbsd.rs @@ -3,7 +3,7 @@ //! `getrandom(2)` was introduced in NetBSD 10. To support older versions we //! implement our own weak linkage to it, and provide a fallback based on the //! KERN_ARND sysctl. -use crate::{util_libc::sys_fill_exact, Error}; +use crate::Error; use core::{ cmp, ffi::c_void, @@ -12,6 +12,9 @@ use core::{ sync::atomic::{AtomicPtr, Ordering}, }; +#[path = "../util_libc.rs"] +mod util_libc; + unsafe extern "C" fn polyfill_using_kern_arand( buf: *mut c_void, buflen: libc::size_t, @@ -69,7 +72,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { fptr = init(); } let fptr = unsafe { mem::transmute::<*mut c_void, GetRandomFn>(fptr) }; - sys_fill_exact(dest, |buf| unsafe { + util_libc::sys_fill_exact(dest, |buf| unsafe { fptr(buf.as_mut_ptr().cast::(), buf.len(), 0) }) } diff --git a/src/rdrand.rs b/src/backends/rdrand.rs similarity index 96% rename from src/rdrand.rs rename to src/backends/rdrand.rs index 2f2aed14..0a278b9a 100644 --- a/src/rdrand.rs +++ b/src/backends/rdrand.rs @@ -1,7 +1,10 @@ //! RDRAND backend for x86(-64) targets -use crate::{lazy::LazyBool, util::slice_as_uninit, Error}; +use crate::{util::slice_as_uninit, Error}; use core::mem::{size_of, MaybeUninit}; +#[path = "../lazy.rs"] +mod lazy; + #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] compile_error!("`rdrand` backend can be enabled only for x86 and x86-64 targets!"); @@ -97,7 +100,7 @@ fn is_rdrand_good() -> bool { } pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - static RDRAND_GOOD: LazyBool = LazyBool::new(); + static RDRAND_GOOD: lazy::LazyBool = lazy::LazyBool::new(); if !RDRAND_GOOD.unsync_init(is_rdrand_good) { return Err(Error::NO_RDRAND); } diff --git a/src/rndr.rs b/src/backends/rndr.rs similarity index 97% rename from src/rndr.rs rename to src/backends/rndr.rs index 573fa9a4..b6805b20 100644 --- a/src/rndr.rs +++ b/src/backends/rndr.rs @@ -84,12 +84,12 @@ fn is_rndr_available() -> bool { (id_aa64isar0 >> 60) & 0xf >= 1 } - #[path = "../src/lazy.rs"] mod lazy; + #[path = "../lazy.rs"] mod lazy; static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new(); RNDR_GOOD.unsync_init(mrs_check) } else if #[cfg(feature = "std")] { extern crate std; - #[path = "../src/lazy.rs"] mod lazy; + #[path = "../lazy.rs"] mod lazy; static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new(); RNDR_GOOD.unsync_init(|| std::arch::is_aarch64_feature_detected!("rand")) } else { diff --git a/src/solaris.rs b/src/backends/solaris.rs similarity index 83% rename from src/solaris.rs rename to src/backends/solaris.rs index f2470e8a..a9a26804 100644 --- a/src/solaris.rs +++ b/src/backends/solaris.rs @@ -12,9 +12,12 @@ //! For more information, see the man page linked in lib.rs and this blog post: //! https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2 //! which also explains why this crate should not use getentropy(2). -use crate::{util_libc::last_os_error, Error}; +use crate::Error; use core::{ffi::c_void, mem::MaybeUninit}; +#[path = "../util_libc.rs"] +mod util_libc; + const MAX_BYTES: usize = 1024; pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { @@ -24,8 +27,11 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { // In case the man page has a typo, we also check for negative ret. // If getrandom(2) succeeds, it should have completely filled chunk. match usize::try_from(ret) { - Ok(ret) if ret == chunk.len() => {} // Good. Keep going. - Ok(0) => return Err(last_os_error()), // The syscall failed. + // Good. Keep going. + Ok(ret) if ret == chunk.len() => {} + // The syscall failed. + Ok(0) => return Err(util_libc::last_os_error()), + // All other cases should be impossible. _ => return Err(Error::UNEXPECTED), } } diff --git a/src/solid.rs b/src/backends/solid.rs similarity index 100% rename from src/solid.rs rename to src/backends/solid.rs diff --git a/src/use_file.rs b/src/backends/use_file.rs similarity index 97% rename from src/use_file.rs rename to src/backends/use_file.rs index 45377572..86dfb48c 100644 --- a/src/use_file.rs +++ b/src/backends/use_file.rs @@ -1,14 +1,14 @@ //! Implementations that just need to read from a file -use crate::{ - util_libc::{last_os_error, sys_fill_exact}, - Error, -}; +use crate::Error; use core::{ ffi::c_void, mem::MaybeUninit, sync::atomic::{AtomicI32, Ordering}, }; +#[path = "../util_libc.rs"] +pub(super) mod util_libc; + /// For all platforms, we use `/dev/urandom` rather than `/dev/random`. /// For more information see the linked man pages in lib.rs. /// - On Linux, "/dev/urandom is preferred and sufficient in all use cases". @@ -42,7 +42,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { if fd == FD_UNINIT || fd == FD_ONGOING_INIT { fd = open_or_wait()?; } - sys_fill_exact(dest, |buf| unsafe { + util_libc::sys_fill_exact(dest, |buf| unsafe { libc::read(fd, buf.as_mut_ptr().cast::(), buf.len()) }) } @@ -65,7 +65,7 @@ fn open_readonly(path: &[u8]) -> Result { if fd >= 0 { return Ok(fd); } - let err = last_os_error(); + let err = util_libc::last_os_error(); // We should try again if open() was interrupted. if err.raw_os_error() != Some(libc::EINTR) { return Err(err); @@ -142,7 +142,7 @@ mod sync { #[cfg(any(target_os = "android", target_os = "linux"))] mod sync { - use super::{last_os_error, open_readonly, Error, FD, FD_ONGOING_INIT}; + use super::{open_readonly, util_libc::last_os_error, Error, FD, FD_ONGOING_INIT}; /// Wait for atomic `FD` to change value from `FD_ONGOING_INIT` to something else. /// diff --git a/src/vxworks.rs b/src/backends/vxworks.rs similarity index 91% rename from src/vxworks.rs rename to src/backends/vxworks.rs index 6d8a4bf9..d595d17b 100644 --- a/src/vxworks.rs +++ b/src/backends/vxworks.rs @@ -1,11 +1,14 @@ //! Implementation for VxWorks -use crate::{util_libc::last_os_error, Error}; +use crate::Error; use core::{ cmp::Ordering::{Equal, Greater, Less}, mem::MaybeUninit, sync::atomic::{AtomicBool, Ordering::Relaxed}, }; +#[path = "../util_libc.rs"] +mod util_libc; + pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { static RNG_INIT: AtomicBool = AtomicBool::new(false); while !RNG_INIT.load(Relaxed) { @@ -32,7 +35,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { let p: *mut libc::c_uchar = chunk.as_mut_ptr().cast(); let ret = unsafe { libc::randABytes(p, chunk_len) }; if ret != 0 { - return Err(last_os_error()); + return Err(util_libc::last_os_error()); } } Ok(()) diff --git a/src/wasi.rs b/src/backends/wasi.rs similarity index 100% rename from src/wasi.rs rename to src/backends/wasi.rs diff --git a/src/wasm_js.rs b/src/backends/wasm_js.rs similarity index 98% rename from src/wasm_js.rs rename to src/backends/wasm_js.rs index da70d5ad..5cdca578 100644 --- a/src/wasm_js.rs +++ b/src/backends/wasm_js.rs @@ -30,7 +30,7 @@ thread_local!( static RNG_SOURCE: Result = getrandom_init(); ); -pub(crate) fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { +pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { RNG_SOURCE.with(|result| { let source = result.as_ref().map_err(|&e| e)?; diff --git a/src/windows.rs b/src/backends/windows.rs similarity index 100% rename from src/windows.rs rename to src/backends/windows.rs diff --git a/src/windows7.rs b/src/backends/windows7.rs similarity index 100% rename from src/windows7.rs rename to src/backends/windows7.rs diff --git a/src/error_impls.rs b/src/error_std_impls.rs similarity index 100% rename from src/error_impls.rs rename to src/error_std_impls.rs diff --git a/src/lib.rs b/src/lib.rs index bc7b3570..b0034588 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,154 +33,14 @@ extern crate cfg_if; use core::mem::MaybeUninit; +mod backends; mod error; mod util; #[cfg(feature = "std")] -mod error_impls; +mod error_std_impls; pub use crate::error::Error; -use crate::util::{slice_as_uninit_mut, slice_assume_init_mut}; - -// System-specific implementations. -// -// These should all provide fill_inner with the signature -// `fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error>`. -// The function MUST fully initialize `dest` when `Ok(())` is returned. -// The function MUST NOT ever write uninitialized bytes into `dest`, -// regardless of what value it returns. -cfg_if! { - if #[cfg(getrandom_backend = "custom")] { - #[path = "custom.rs"] mod imp; - } 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; - } else if #[cfg(getrandom_backend = "rndr")] { - #[path = "rndr.rs"] mod imp; - } else if #[cfg(getrandom_backend = "wasm_js")] { - #[path = "wasm_js.rs"] mod imp; - } else if #[cfg(getrandom_backend = "esp_idf")] { - #[path = "esp_idf.rs"] mod imp; - } else if #[cfg(any( - target_os = "haiku", - target_os = "redox", - target_os = "nto", - target_os = "aix", - ))] { - mod util_libc; - #[path = "use_file.rs"] mod imp; - } else if #[cfg(any( - target_os = "macos", - target_os = "openbsd", - target_os = "vita", - target_os = "emscripten", - ))] { - mod util_libc; - #[path = "getentropy.rs"] mod imp; - } else if #[cfg(any( - target_os = "dragonfly", - target_os = "freebsd", - target_os = "hurd", - target_os = "illumos", - // Check for target_arch = "arm" to only include the 3DS. Does not - // include the Nintendo Switch (which is target_arch = "aarch64"). - all(target_os = "horizon", target_arch = "arm"), - ))] { - mod util_libc; - #[path = "getrandom.rs"] mod imp; - } else if #[cfg(any( - // Rust supports Android API level 19 (KitKat) [0] and the next upgrade targets - // level 21 (Lollipop) [1], while `getrandom(2)` was added only in - // level 23 (Marshmallow). Note that it applies only to the "old" `target_arch`es, - // RISC-V Android targets sufficiently new API level, same will apply for potential - // new Android `target_arch`es. - // [0]: https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html - // [1]: https://github.com/rust-lang/rust/pull/120593 - all( - target_os = "android", - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "x86", - target_arch = "x86_64", - ), - ), - // Only on these `target_arch`es Rust supports Linux kernel versions (3.2+) - // that precede the version (3.17) in which `getrandom(2)` was added: - // https://doc.rust-lang.org/stable/rustc/platform-support.html - all( - target_os = "linux", - any( - target_arch = "aarch64", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "s390x", - target_arch = "x86", - target_arch = "x86_64", - // Minimum supported Linux kernel version for MUSL targets - // is not specified explicitly (as of Rust 1.77) and they - // are used in practice to target pre-3.17 kernels. - target_env = "musl", - ), - ) - ))] { - mod util_libc; - mod use_file; - #[path = "linux_android_with_fallback.rs"] mod imp; - } else if #[cfg(any(target_os = "android", target_os = "linux"))] { - mod util_libc; - #[path = "linux_android.rs"] mod imp; - } else if #[cfg(target_os = "solaris")] { - mod util_libc; - #[path = "solaris.rs"] mod imp; - } else if #[cfg(target_os = "netbsd")] { - mod util_libc; - #[path = "netbsd.rs"] mod imp; - } else if #[cfg(target_os = "fuchsia")] { - #[path = "fuchsia.rs"] mod imp; - } else if #[cfg(any( - target_os = "ios", - target_os = "visionos", - target_os = "watchos", - target_os = "tvos", - ))] { - #[path = "apple-other.rs"] mod imp; - } else if #[cfg(all(target_arch = "wasm32", target_os = "wasi"))] { - #[path = "wasi.rs"] mod imp; - } else if #[cfg(target_os = "hermit")] { - #[path = "hermit.rs"] mod imp; - } else if #[cfg(target_os = "vxworks")] { - mod util_libc; - #[path = "vxworks.rs"] mod imp; - } else if #[cfg(target_os = "solid_asp3")] { - #[path = "solid.rs"] mod imp; - } else if #[cfg(all(windows, target_vendor = "win7"))] { - #[path = "windows7.rs"] mod imp; - } else if #[cfg(windows)] { - #[path = "windows.rs"] mod imp; - } else if #[cfg(all(target_arch = "x86_64", target_env = "sgx"))] { - mod lazy; - #[path = "rdrand.rs"] mod imp; - } else if #[cfg(all( - any(target_arch = "wasm32", target_arch = "wasm64"), - target_os = "unknown", - ))] { - compile_error!("the wasm*-unknown-unknown targets are not supported by \ - default, you may need to enable the \"wasm_js\" \ - configuration flag. For more information see: \ - https://docs.rs/getrandom/#webassembly-support"); - } else { - compile_error!("target is not supported. You may need to define \ - a custom backend see: \ - https://docs.rs/getrandom/#custom-backends"); - } -} /// Fill `dest` with random bytes from the system's preferred random number source. /// @@ -208,7 +68,7 @@ pub fn fill(dest: &mut [u8]) -> Result<(), Error> { // SAFETY: The `&mut MaybeUninit<_>` reference doesn't escape, // and `fill_uninit` guarantees it will never de-initialize // any part of `dest`. - fill_uninit(unsafe { slice_as_uninit_mut(dest) })?; + fill_uninit(unsafe { util::slice_as_uninit_mut(dest) })?; Ok(()) } @@ -237,7 +97,7 @@ pub fn fill(dest: &mut [u8]) -> Result<(), Error> { #[inline] pub fn fill_uninit(dest: &mut [MaybeUninit]) -> Result<&mut [u8], Error> { if !dest.is_empty() { - imp::fill_inner(dest)?; + backends::fill_inner(dest)?; } #[cfg(getrandom_sanitize)] @@ -253,6 +113,6 @@ pub fn fill_uninit(dest: &mut [MaybeUninit]) -> Result<&mut [u8], Error> { #[cfg(sanitize = "memory")] __msan_unpoison(dest.as_mut_ptr().cast(), dest.len()); - slice_assume_init_mut(dest) + util::slice_assume_init_mut(dest) }) }