From f2d76625d54b2eae398634e055ef143b3c3c1db1 Mon Sep 17 00:00:00 2001 From: Joseph Richey Date: Sun, 23 Oct 2022 13:46:01 -0700 Subject: [PATCH] Solaris: consistantly use /dev/random source (#310) On Solaris, we opt to use /dev/random source instead of /dev/urandom due to reasons explained in the comments and [in this Solaris blog post](https://blogs.oracle.com/solaris/post/solaris-new-system-calls-getentropy2-and-getrandom2). However, we haven't been making the same choice when getting randomness via the `getrandom(2)` function, as we just pass `0` for the flags. We [used to](https://github.com/rust-random/rand/pull/730/files#diff-694d4302a3ff2a976f2fbd34bc05ada22ee61a4e21d2d985beab27f7a809268fR151) always set `GRND_RANDOM`, but that was removed in the move from `OsRng` to this crate. For context, https://github.com/rust-random/rand/pull/730, https://github.com/rust-random/getrandom/pull/9, and https://github.com/rust-random/getrandom/pull/51 are the major changes to the Solaris/Illumos implementation over the years. See the solaris documentation for: - [`getrandom(2)`](https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html) - [`urandom(4)`](https://docs.oracle.com/cd/E88353_01/html/E37851/urandom-4d.html) I also updated the doucmentation to better reflect when [Illumos added the `getrandom(2)` function](https://www.illumos.org/issues/9971#change-23483). Signed-off-by: Joe Richey --- Cargo.toml | 2 +- src/solaris_illumos.rs | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6165cf11..320aa581 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ compiler_builtins = { version = "0.1", optional = true } core = { version = "1.0", optional = true, package = "rustc-std-workspace-core" } [target.'cfg(unix)'.dependencies] -libc = { version = "0.2.120", default-features = false } +libc = { version = "0.2.128", default-features = false } [target.'cfg(target_os = "wasi")'.dependencies] wasi = { version = "0.11", default-features = false } diff --git a/src/solaris_illumos.rs b/src/solaris_illumos.rs index bf669fb6..501c610d 100644 --- a/src/solaris_illumos.rs +++ b/src/solaris_illumos.rs @@ -8,12 +8,11 @@ //! Implementation for the Solaris family //! -//! Read from `/dev/random`, with chunks of limited size (256 bytes). //! `/dev/random` uses the Hash_DRBG with SHA512 algorithm from NIST SP 800-90A. //! `/dev/urandom` uses the FIPS 186-2 algorithm, which is considered less -//! secure. We choose to read from `/dev/random`. +//! secure. We choose to read from `/dev/random` (and use GRND_RANDOM). //! -//! Since Solaris 11.3 and mid-2015 illumos, the `getrandom` syscall is available. +//! Solaris 11.3 and late-2018 illumos added the getrandom(2) libc function. //! To make sure we can compile on both Solaris and its derivatives, as well as //! function, we check for the existence of getrandom(2) in libc by calling //! libc::dlsym. @@ -24,21 +23,23 @@ use crate::{ }; use core::mem::{self, MaybeUninit}; -#[cfg(target_os = "illumos")] -type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t; -#[cfg(target_os = "solaris")] -type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::c_int; +static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") }; +type GetRandomFn = + unsafe extern "C" fn(*mut libc::c_void, libc::size_t, libc::c_uint) -> libc::ssize_t; pub fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - // getrandom(2) was introduced in Solaris 11.3 for Illumos in 2015. - static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") }; if let Some(fptr) = GETRANDOM.ptr() { let func: GetRandomFn = unsafe { mem::transmute(fptr) }; // 256 bytes is the lowest common denominator across all the Solaris // derived platforms for atomically obtaining random data. for chunk in dest.chunks_mut(256) { sys_fill_exact(chunk, |buf| unsafe { - func(buf.as_mut_ptr() as *mut u8, buf.len(), 0) as libc::ssize_t + // A cast is needed for the flags as libc uses the wrong type. + func( + buf.as_mut_ptr() as *mut libc::c_void, + buf.len(), + libc::GRND_RANDOM as libc::c_uint, + ) })? } Ok(())