Skip to content

Commit

Permalink
Switch to using the arandom sysctl on NetBSD (same as FreeBSD). (#115)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
alarixnia authored and newpavlov committed Oct 23, 2019
1 parent 6b4925a commit 2fa1bba
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
28 changes: 16 additions & 12 deletions src/freebsd.rs → src/bsd_arandom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -27,19 +25,25 @@ 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
}
}

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)
}
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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")] {
Expand All @@ -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")] {
Expand Down
2 changes: 1 addition & 1 deletion src/use_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 2fa1bba

Please sign in to comment.