Skip to content

Commit

Permalink
util_libc: Clarify type safety of libc::syscall usage.
Browse files Browse the repository at this point in the history
  • Loading branch information
briansmith committed May 31, 2024
1 parent 74cd1ed commit 2cdf331
Showing 1 changed file with 25 additions and 8 deletions.
33 changes: 25 additions & 8 deletions src/util_libc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,29 @@ pub fn open_readonly(path: &[u8]) -> Result<libc::c_int, Error> {
/// Thin wrapper around the `getrandom()` Linux system call
#[cfg(any(target_os = "android", target_os = "linux"))]
pub fn getrandom_syscall(buf: &mut [MaybeUninit<u8>]) -> libc::ssize_t {
unsafe {
libc::syscall(
libc::SYS_getrandom,
buf.as_mut_ptr().cast::<core::ffi::c_void>(),
buf.len(),
0,
) as libc::ssize_t
}
// Rust requires object to be smaller than `isize::MAX` bytes, so there is
// no real truncation here, even when running
debug_assert!(buf.len() <= isize::MAX.unsigned_abs());

// TODO: Add support for x32 and similar ABIs?

// pointers can be passed to libc::syscall.
const _: () = assert!(core::mem::size_of::<libc::c_long>() == core::mem::size_of::<*mut core::ffi::c_void>());
let ptr = buf.as_mut_ptr().cast::<core::ffi::c_void>();

// usize values can be passed to libc::syscall.
const _: () =
assert!(core::mem::size_of::<libc::c_long>() == core::mem::size_of::<libc::ssize_t>());
let len: usize = buf.len();

const ZERO: libc::c_ulong = 0;

let res: libc::c_long = unsafe { libc::syscall(libc::SYS_getrandom, ptr, len, ZERO) };

// c_long to ssize_t conversion is lossless.
const _: () =
assert!(core::mem::size_of::<libc::c_long>() == core::mem::size_of::<libc::ssize_t>());
#[allow(clippy::cast_possible_truncation)]
let res = res as libc::ssize_t;
res
}

0 comments on commit 2cdf331

Please sign in to comment.