Skip to content

Commit f875dac

Browse files
committed
rand: don't block before random pool is initialized
If we attempt a read with getrandom() on Linux the syscall can block before the random pool is initialized unless the GRND_NONBLOCK flag is passed. This flag causes getrandom() to instead return EAGAIN while the pool is uninitialized. To avoid downstream users of crate or std functionality that have no ability to avoid this blocking behavior this change causes Rust to read bytes from /dev/urandom while getrandom() would block and once getrandom() is available to use that. Fixes #32953. Signed-off-by: Doug Goldstein <cardoe@cardoe.com>
1 parent d007824 commit f875dac

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

Diff for: src/libstd/sys/unix/rand.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@ mod imp {
4141
#[cfg(target_arch = "aarch64")]
4242
const NR_GETRANDOM: libc::c_long = 278;
4343

44+
const GRND_NONBLOCK: libc::c_uint = 0x0001;
45+
4446
unsafe {
45-
libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
47+
libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)
4648
}
4749
}
4850

@@ -63,6 +65,11 @@ mod imp {
6365
let err = errno() as libc::c_int;
6466
if err == libc::EINTR {
6567
continue;
68+
} else if err == libc::EAGAIN {
69+
let reader = File::open("/dev/urandom").expect("Unable to open /dev/urandom");
70+
let mut reader_rng = ReaderRng::new(reader);
71+
reader_rng.fill_bytes(& mut v[read..]);
72+
read += v.len() as usize;
6673
} else {
6774
panic!("unexpected getrandom error: {}", err);
6875
}

0 commit comments

Comments
 (0)