-
Notifications
You must be signed in to change notification settings - Fork 216
Conditionally disable file fallback for Android and Linux #396
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,7 @@ | ||
//! Implementation for Linux / Android | ||
use crate::{ | ||
lazy::LazyBool, | ||
util_libc::{last_os_error, sys_fill_exact}, | ||
{use_file, Error}, | ||
}; | ||
//! Implementation for Linux / Android without `/dev/urandom` fallback | ||
use crate::{util_libc, Error}; | ||
use core::mem::MaybeUninit; | ||
|
||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { | ||
// getrandom(2) was introduced in Linux 3.17 | ||
static HAS_GETRANDOM: LazyBool = LazyBool::new(); | ||
if HAS_GETRANDOM.unsync_init(is_getrandom_available) { | ||
sys_fill_exact(dest, |buf| unsafe { | ||
getrandom(buf.as_mut_ptr() as *mut libc::c_void, buf.len(), 0) | ||
}) | ||
} else { | ||
use_file::getrandom_inner(dest) | ||
} | ||
} | ||
|
||
fn is_getrandom_available() -> bool { | ||
let res = unsafe { getrandom(core::ptr::null_mut(), 0, libc::GRND_NONBLOCK) }; | ||
if res < 0 { | ||
match last_os_error().raw_os_error() { | ||
Some(libc::ENOSYS) => false, // No kernel support | ||
Some(libc::EPERM) => false, // Blocked by seccomp | ||
_ => true, | ||
} | ||
} else { | ||
true | ||
} | ||
} | ||
|
||
unsafe fn getrandom( | ||
newpavlov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
buf: *mut libc::c_void, | ||
buflen: libc::size_t, | ||
flags: libc::c_uint, | ||
) -> libc::ssize_t { | ||
libc::syscall(libc::SYS_getrandom, buf, buflen, flags) as libc::ssize_t | ||
util_libc::sys_fill_exact(dest, util_libc::getrandom_syscall) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
//! Implementation for Linux / Android with `/dev/urandom` fallback | ||
use crate::{ | ||
lazy::LazyBool, | ||
util_libc::{getrandom_syscall, last_os_error, sys_fill_exact}, | ||
{use_file, Error}, | ||
}; | ||
use core::mem::MaybeUninit; | ||
|
||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { | ||
// getrandom(2) was introduced in Linux 3.17 | ||
static HAS_GETRANDOM: LazyBool = LazyBool::new(); | ||
if HAS_GETRANDOM.unsync_init(is_getrandom_available) { | ||
sys_fill_exact(dest, getrandom_syscall) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry to contradict my earlier suggestion, but I think I have a better one: Let's change this line to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need |
||
} else { | ||
use_file::getrandom_inner(dest) | ||
} | ||
} | ||
|
||
fn is_getrandom_available() -> bool { | ||
if getrandom_syscall(&mut []) < 0 { | ||
match last_os_error().raw_os_error() { | ||
Some(libc::ENOSYS) => false, // No kernel support | ||
// The fallback on EPERM is intentionally not done on Android since this workaround | ||
// seems to be needed only for specific Linux-based products that aren't based | ||
// on Android. See https://github.com/rust-random/getrandom/issues/229. | ||
#[cfg(target_os = "linux")] | ||
Some(libc::EPERM) => false, // Blocked by seccomp | ||
_ => true, | ||
} | ||
} else { | ||
true | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.