-
Notifications
You must be signed in to change notification settings - Fork 256
Expand file tree
/
Copy pathlinux_android_with_fallback.rs
More file actions
35 lines (32 loc) · 1.33 KB
/
linux_android_with_fallback.rs
File metadata and controls
35 lines (32 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//! Implementation for Linux / Android with `/dev/urandom` fallback
use crate::{lazy::LazyBool, linux_android, use_file, util_libc::last_os_error, 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) {
linux_android::getrandom_inner(dest)
} else {
// prevent inlining of the fallback implementation
#[inline(never)]
fn inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
use_file::getrandom_inner(dest)
}
inner(dest)
}
}
fn is_getrandom_available() -> bool {
if linux_android::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
}
}