forked from rust-random/getrandom
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds a backend based on the rustix crate. The main advantage of rustix, in addition to greater safety, is that it uses raw syscalls instead of going through libc. I've tried to modify the existing libc code as little as possible, in order to make this change as auditable as possible. I haven't touched the pthreads code yet, as that's a little tricky. This exists for discussion purposes. cc rust-random#401 Signed-off-by: John Nunley <[email protected]>
- Loading branch information
Showing
7 changed files
with
149 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,12 @@ | ||
//! Implementation for Linux / Android without `/dev/urandom` fallback | ||
use crate::{util_libc, Error}; | ||
use crate::Error; | ||
use core::mem::MaybeUninit; | ||
|
||
#[cfg(not(feature = "rustix"))] | ||
use crate::util_libc; | ||
#[cfg(feature = "rustix")] | ||
use crate::util_rustix as util_libc; | ||
|
||
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> { | ||
util_libc::sys_fill_exact(dest, util_libc::getrandom_syscall) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
//! Utilities for using rustix. | ||
//! | ||
//! At this point in time it is only used on Linux-like operating systems. | ||
use crate::Error; | ||
use core::convert::TryInto; | ||
use core::mem::MaybeUninit; | ||
use core::num::NonZeroU32; | ||
|
||
use rustix::fd::OwnedFd; | ||
use rustix::fs; | ||
use rustix::io::Errno; | ||
use rustix::rand; | ||
|
||
/// Convert a Rustix error to one of our errors. | ||
pub(crate) fn cvt(err: Errno) -> Error { | ||
match TryInto::<u32>::try_into(err.raw_os_error()) | ||
.ok() | ||
.and_then(NonZeroU32::new) | ||
{ | ||
Some(code) => Error::from(code), | ||
None => Error::ERRNO_NOT_POSITIVE, | ||
} | ||
} | ||
|
||
/// Fill a buffer by repeatedly invoking a `rustix` call. | ||
pub(crate) fn sys_fill_exact( | ||
mut buf: &mut [MaybeUninit<u8>], | ||
fill: impl Fn(&mut [MaybeUninit<u8>]) -> Result<(&mut [u8], &mut [MaybeUninit<u8>]), Errno>, | ||
) -> Result<(), Error> { | ||
while !buf.is_empty() { | ||
// Read into the buffer. | ||
match fill(buf) { | ||
Err(err) => return Err(cvt(err)), | ||
Ok((_filled, unfilled)) => { | ||
buf = unfilled; | ||
} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Open a file as read-only. | ||
pub(crate) fn open_readonly(path: &str) -> Result<OwnedFd, Error> { | ||
loop { | ||
match fs::open( | ||
path, | ||
fs::OFlags::CLOEXEC | fs::OFlags::RDONLY, | ||
fs::Mode::empty(), | ||
) { | ||
Ok(file) => return Ok(file), | ||
Err(Errno::INTR) => continue, | ||
Err(err) => return Err(cvt(err)), | ||
} | ||
} | ||
} | ||
|
||
pub(crate) fn getrandom_syscall( | ||
buf: &mut [MaybeUninit<u8>], | ||
) -> Result<(&mut [u8], &mut [MaybeUninit<u8>]), Errno> { | ||
rand::getrandom_uninit(buf, rand::GetRandomFlags::empty()) | ||
} |