X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=library%2Fstd%2Fsrc%2Fsys%2Funix%2Frand.rs;h=a6fe07873d7ee4263b9362d9a5dda75c35916582;hb=0c14ad4d9fe83e737d7b8db0c2520ef54c99926e;hp=40885417308b80a2007591f17af0984a44215831;hpb=e413c96ec597f099c2cc8954f643a366f07aba75;p=rust.git diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index 40885417308..a6fe07873d7 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -137,9 +137,11 @@ pub fn fill_bytes(v: &mut [u8]) { } } -#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))] +#[cfg(target_os = "macos")] mod imp { - use crate::io; + use crate::fs::File; + use crate::io::Read; + use crate::sys::os::errno; use crate::sys::weak::weak; use libc::{c_int, c_void, size_t}; @@ -153,7 +155,7 @@ fn getentropy_fill_bytes(v: &mut [u8]) -> bool { for s in v.chunks_mut(256) { let ret = unsafe { f(s.as_mut_ptr() as *mut c_void, s.len()) }; if ret == -1 { - panic!("unexpected getentropy error: {}", io::Error::last_os_error()); + panic!("unexpected getentropy error: {}", errno()); } } true @@ -161,64 +163,14 @@ fn getentropy_fill_bytes(v: &mut [u8]) -> bool { .unwrap_or(false) } - #[cfg(target_os = "macos")] - fn fallback_fill_bytes(v: &mut [u8]) { - use crate::fs::File; - use crate::io::Read; - - let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom"); - file.read_exact(v).expect("failed to read /dev/urandom") - } - - // On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with - // `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded - // from `/dev/random` and which runs on its own thread accessed via GCD. - // - // This is very heavyweight compared to the alternatives, but they may not be usable: - // - `getentropy` was added in iOS 10, but we support a minimum of iOS 7 - // - `/dev/urandom` is not accessible inside the iOS app sandbox. - // - // Therefore `SecRandomCopyBytes` is only used on older iOS versions where no - // better options are present. - #[cfg(target_os = "ios")] - fn fallback_fill_bytes(v: &mut [u8]) { - use crate::ptr; - - enum SecRandom {} - - #[allow(non_upper_case_globals)] - const kSecRandomDefault: *const SecRandom = ptr::null(); - - extern "C" { - fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int; - } - - let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) }; - if ret == -1 { - panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); - } - } - - // All supported versions of watchOS (>= 5) have support for `getentropy`. - #[cfg(target_os = "watchos")] - #[cold] - fn fallback_fill_bytes(_: &mut [u8]) { - unreachable!() - } - pub fn fill_bytes(v: &mut [u8]) { if getentropy_fill_bytes(v) { return; } - // Older macOS versions (< 10.12) don't support `getentropy`. Fallback to - // reading from `/dev/urandom` on these systems. - // - // Older iOS versions (< 10) don't support it either. Fallback to - // `SecRandomCopyBytes` on these systems. On watchOS, this is unreachable - // because the minimum supported version is 5 while `getentropy` became accessible - // in 3. - fallback_fill_bytes(v) + // for older macos which doesn't support getentropy + let mut file = File::open("/dev/urandom").expect("failed to open /dev/urandom"); + file.read_exact(v).expect("failed to read /dev/urandom") } } @@ -237,6 +189,36 @@ pub fn fill_bytes(v: &mut [u8]) { } } +// On iOS and MacOS `SecRandomCopyBytes` calls `CCRandomCopyBytes` with +// `kCCRandomDefault`. `CCRandomCopyBytes` manages a CSPRNG which is seeded +// from `/dev/random` and which runs on its own thread accessed via GCD. +// This seems needlessly heavyweight for the purposes of generating two u64s +// once per thread in `hashmap_random_keys`. Therefore `SecRandomCopyBytes` is +// only used on iOS where direct access to `/dev/urandom` is blocked by the +// sandbox. +#[cfg(any(target_os = "ios", target_os = "watchos"))] +mod imp { + use crate::io; + use crate::ptr; + use libc::{c_int, size_t}; + + enum SecRandom {} + + #[allow(non_upper_case_globals)] + const kSecRandomDefault: *const SecRandom = ptr::null(); + + extern "C" { + fn SecRandomCopyBytes(rnd: *const SecRandom, count: size_t, bytes: *mut u8) -> c_int; + } + + pub fn fill_bytes(v: &mut [u8]) { + let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, v.len(), v.as_mut_ptr()) }; + if ret == -1 { + panic!("couldn't generate random bytes: {}", io::Error::last_os_error()); + } + } +} + #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] mod imp { use crate::ptr;