-
Notifications
You must be signed in to change notification settings - Fork 182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Switch to using the arandom sysctl on NetBSD (same as FreeBSD). #115
Conversation
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Niacat thanks for the contribution. I hope this works, so that we can have the weird We would ideally like to test this. It's not a hard requirement (as we weren't testing FreeBSD before), but it would be nice. Right now, I wouldn't know how to go about making sure this change functions on a FreeBSD system. Do you have a setup for testing FreeBSD Rust stuff in CI? |
in sysctl(7):
(this actually means it uses chacha20, as arc4random does on NetBSD). the arguments are documented in
on the limits of the function: it can return up to 256 bytes in a single system call, for reasons that are unclear to me. anything larger fails. (possibly historical reasons, to avoid trivial DoS attacks). however, it can be called repeatedly without blocking.
The documentation has probably confused people here. /dev/random isn't supposed to be polled except at boot, presumably by init, and not by application software or libraries.
personally no. I'm not a rust programmer or FreeBSD user, just a NetBSD developer. |
Perfect, thanks for the link. It looks like
You're correct here, I wrote that code with Linux specifically in mind, and then just had NetBSD code use it without much additional thought. That was clearly wrong.
facepalm the above should all say NetBSD, rather than FreeBSD. |
As for testing, it looks like none of the major CI services have NetBSD, Cirrus CI has FreeBSD. Both FreeBSD and NetBSD are Tier 2 Targets, so we probobly should have some testing for them. However, that shouldn't block this PR. |
One last thing, this current implementation will check for Despite NetBSD not having |
Hm, I think it may be use #[cfg(target_os = "freebsd")]
type GetRandomFn = ...;
fn kern_arnd(buf: &mut [u8]) -> libc::ssize_t { .. }
#[cfg(target_os = "freebsd")]
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { .. }
#[cfg(target_os = "netbsd")]
pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { .. } It's not so much code and we will not do useless stuff on NetBSD. |
Wait, by fails you mean it returns an error for buffers larger than 256 bytes? Right now we assume that for large buffers it will return how many bytes have been written. |
I think it just does a short read for long buffers, instead of failing. I think this is the right part of the kernel source. It also looks like the NetBSD OpenSSL implementation assumes that keyctl will just do short (<= 256 byte) reads when given long buffers. |
Added, I just moved all of the FreeBSD specific code/declarations to a |
This system call is present on all supported NetBSD versions and provides an endless stream of non-blocking random data from the kernel's ChaCha20-based CSPRNG. It doesn't require a file descriptor to be opened. The system call is documented here (under kern.arandom): https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-7.0 And defined here: https://nxr.netbsd.org/xref/src/sys/sys/sysctl.h#273 The semantics are the same as FreeBSD so reading 256 bytes per call is fine. Similar change for getrandom crate: rust-random/getrandom#115
Use KERN_ARND syscall for random numbers on NetBSD, same as FreeBSD. This system call is present on all supported NetBSD versions and provides an endless stream of non-blocking random data from the kernel's ChaCha20-based CSPRNG. It doesn't require a file like `/dev/urandom` to be opened. The system call is documented here (under kern.arandom): https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+7+NetBSD-7.0 And defined here: https://nxr.netbsd.org/xref/src/sys/sys/sysctl.h#273 The semantics are the same as FreeBSD so reading 256 bytes per call is fine. Similar change for getrandom crate: rust-random/getrandom#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).