Skip to content

Commit 2fa1bba

Browse files
alarixnianewpavlov
authored andcommitted
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).
1 parent 6b4925a commit 2fa1bba

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

src/freebsd.rs renamed to src/bsd_arandom.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@
66
// option. This file may not be copied, modified, or distributed
77
// except according to those terms.
88

9-
//! Implementation for FreeBSD
10-
use crate::util_libc::{sys_fill_exact, Weak};
9+
//! Implementation for FreeBSD and NetBSD
10+
use crate::util_libc::sys_fill_exact;
1111
use crate::Error;
12-
use core::{mem, ptr};
13-
14-
type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
12+
use core::ptr;
1513

1614
fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
1715
static MIB: [libc::c_int; 2] = [libc::CTL_KERN, libc::KERN_ARND];
@@ -27,19 +25,25 @@ fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t {
2725
)
2826
};
2927
if ret == -1 {
30-
error!("freebsd: kern.arandom syscall failed");
28+
error!("sysctl kern.arandom: syscall failed");
3129
-1
3230
} else {
3331
len as libc::ssize_t
3432
}
3533
}
3634

3735
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
38-
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
39-
if let Some(fptr) = GETRANDOM.ptr() {
40-
let func: GetRandomFn = unsafe { mem::transmute(fptr) };
41-
sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) })
42-
} else {
43-
sys_fill_exact(dest, kern_arnd)
36+
#[cfg(target_os = "freebsd")]
37+
{
38+
use crate::util_libc::Weak;
39+
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
40+
type GetRandomFn =
41+
unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) -> libc::ssize_t;
42+
43+
if let Some(fptr) = GETRANDOM.ptr() {
44+
let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
45+
return sys_fill_exact(dest, |buf| unsafe { func(buf.as_mut_ptr(), buf.len(), 0) });
46+
}
4447
}
48+
sys_fill_exact(dest, kern_arnd)
4549
}

src/lib.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//! | iOS | [`SecRandomCopyBytes`][4]
1919
//! | FreeBSD | [`getrandom()`][21] if available, otherwise [`kern.arandom`][5]
2020
//! | OpenBSD | [`getentropy`][6]
21-
//! | NetBSD | [`/dev/urandom`][7] after successfully polling `/dev/random`
21+
//! | NetBSD | [`kern.arandom`][7]
2222
//! | Dragonfly BSD | [`/dev/random`][8]
2323
//! | Solaris, illumos | [`getrandom`][9] system call if available, otherwise [`/dev/random`][10]
2424
//! | Fuchsia OS | [`cprng_draw`][11]
@@ -104,7 +104,7 @@
104104
//! [4]: https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc
105105
//! [5]: https://www.freebsd.org/cgi/man.cgi?query=random&sektion=4
106106
//! [6]: https://man.openbsd.org/getentropy.2
107-
//! [7]: http://netbsd.gw.com/cgi-bin/man-cgi?random+4+NetBSD-current
107+
//! [7]: https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-8.0
108108
//! [8]: https://leaf.dragonflybsd.org/cgi/web-man?command=random&section=4
109109
//! [9]: https://docs.oracle.com/cd/E88353_01/html/E37841/getrandom-2.html
110110
//! [10]: https://docs.oracle.com/cd/E86824_01/html/E54777/random-7d.html
@@ -198,7 +198,7 @@ cfg_if! {
198198
} else if #[cfg(target_os = "emscripten")] {
199199
#[path = "use_file.rs"] mod imp;
200200
} else if #[cfg(target_os = "freebsd")] {
201-
#[path = "freebsd.rs"] mod imp;
201+
#[path = "bsd_arandom.rs"] mod imp;
202202
} else if #[cfg(target_os = "fuchsia")] {
203203
#[path = "fuchsia.rs"] mod imp;
204204
} else if #[cfg(target_os = "haiku")] {
@@ -212,7 +212,7 @@ cfg_if! {
212212
} else if #[cfg(target_os = "macos")] {
213213
#[path = "macos.rs"] mod imp;
214214
} else if #[cfg(target_os = "netbsd")] {
215-
#[path = "use_file.rs"] mod imp;
215+
#[path = "bsd_arandom.rs"] mod imp;
216216
} else if #[cfg(target_os = "openbsd")] {
217217
#[path = "openbsd.rs"] mod imp;
218218
} else if #[cfg(target_os = "redox")] {

src/use_file.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
3939
}
4040

4141
cfg_if! {
42-
if #[cfg(any(target_os = "android", target_os = "linux", target_os = "netbsd"))] {
42+
if #[cfg(any(target_os = "android", target_os = "linux"))] {
4343
fn init_file() -> Option<libc::c_int> {
4444
// Poll /dev/random to make sure it is ok to read from /dev/urandom.
4545
let mut pfd = libc::pollfd {

0 commit comments

Comments
 (0)