Switch to using the arandom sysctl on NetBSD (same as FreeBSD). (#115)

Rename it from freebsd.rs to sysctl_arandom.rs.

NetBSD has been patching rustc for some time to use the FreeBSD
implementation because every single invocation of the compiler
may drain from the entropy pool and cause the next to block.

This can massively inflate build times for rust software, or cause
it to fail entirely, especially in VMs (for example, our Xen package
building cluster).
This commit is contained in:
nia 2019-10-23 09:03:44 +00:00 committed by Artyom Pavlov
parent 6b4925a76d
commit 2fa1bbac80
3 changed files with 21 additions and 17 deletions

View File

@ -6,12 +6,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Implementation for FreeBSD
use crate::util_libc::{sys_fill_exact, Weak};
//! Implementation for FreeBSD and NetBSD
use crate::util_libc::sys_fill_exact;
use crate::Error;
use core::{mem, ptr};
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
use core::ptr;
fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
static MIB: [libc::c_int; 2] = [libc::CTL_KERN, libc::KERN_ARND];
@ -27,7 +25,7 @@ fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
)
};
if ret == -1 {
error!("freebsd: kern.arandom syscall failed");
error!("sysctl kern.arandom: syscall failed");
-1
} else {
len as libc::ssize_t
@ -35,11 +33,17 @@ fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
}
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { mem::transmute(fptr) };
sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) })
} else {
sys_fill_exact(dest, kern_arnd)
#[cfg(target_os = "freebsd")]
{
use crate::util_libc::Weak;
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
type GetRandomFn =
unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
if let Some(fptr) = GETRANDOM.ptr() {
let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
}
}
sys_fill_exact(dest, kern_arnd)
}

View File

@ -18,7 +18,7 @@
//! | iOS | [`SecRandomCopyBytes`][4]
//! | FreeBSD | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
//! | OpenBSD | [`getentropy`][6]
//! | NetBSD | [`/dev/urandom`][7] after successfully polling `/dev/random`
//! | NetBSD | [`kern.arandom`][7]
//! | Dragonfly BSD | [`/dev/random`][8]
//! | Solaris, illumos | [`getrandom`][9] system call if available, otherwise [`/dev/random`][10]
//! | Fuchsia OS | [`cprng_draw`][11]
@ -104,7 +104,7 @@
//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
//! [6]: https://man.openbsd.org/getentropy.2
//! [7]: http://netbsd.gw.com/cgi-bin/man-cgi?random+4+NetBSD-current
//! [7]: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-8.0
//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
//! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
//! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
@ -198,7 +198,7 @@ cfg_if! {
} else if #[cfg(target_os = "emscripten")] {
#[path = "use_file.rs"] mod imp;
} else if #[cfg(target_os = "freebsd")] {
#[path = "freebsd.rs"] mod imp;
#[path = "bsd_arandom.rs"] mod imp;
} else if #[cfg(target_os = "fuchsia")] {
#[path = "fuchsia.rs"] mod imp;
} else if #[cfg(target_os = "haiku")] {
@ -212,7 +212,7 @@ cfg_if! {
} else if #[cfg(target_os = "macos")] {
#[path = "macos.rs"] mod imp;
} else if #[cfg(target_os = "netbsd")] {
#[path = "use_file.rs"] mod imp;
#[path = "bsd_arandom.rs"] mod imp;
} else if #[cfg(target_os = "openbsd")] {
#[path = "openbsd.rs"] mod imp;
} else if #[cfg(target_os = "redox")] {

View File

@ -39,7 +39,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
}
cfg_if! {
if #[cfg(any(target_os = "android", target_os = "linux", target_os = "netbsd"))] {
if #[cfg(any(target_os = "android", target_os = "linux"))] {
fn init_file() -> Option<libc::c_int> {
// Poll /dev/random to make sure it is ok to read from /dev/urandom.
let mut pfd = libc::pollfd {