-
Notifications
You must be signed in to change notification settings - Fork 220
Closed
Description
Lines 4 to 7 in 35808a4
extern "C" { | |
fn sys_read_entropy(buffer: *mut u8, length: usize, flags: u32) -> isize; | |
} | |
Lines 9 to 16 in 35808a4
while !dest.is_empty() { | |
let res = unsafe { sys_read_entropy(dest.as_mut_ptr() as *mut u8, dest.len(), 0) }; | |
if res < 0 { | |
// SAFETY: all Hermit error codes use i32 under the hood: | |
// https://github.com/hermitcore/libhermit-rs/blob/master/src/errno.rs | |
let code = unsafe { NonZeroU32::new_unchecked((-res) as u32) }; | |
return Err(code.into()); | |
} |
- If
res == -sizie::MIN
then(-res)
will overflow. To fix, usechecked_neg()
. - if
res < (i32::MIN as isize)
then(-res) as u32
is a truncating, i.e. lossy conversion. To fix: avoid usingas
for integer conversions and instead useTryInto
for this conversion. - if
(-res) % 0x1_0000_0000 == 0
then(-res) as u32
is zero and thenNonZeroU32::new_unchecked((-res) as u32)
is undefined behavior. To fix, use the safeNonZerou32::new()
instead.
Maybe somewhere hermit guarantees errors codes will never be this large but better to avoid the issue completely.
Something like:
let code = res.checked_neg().map(u32::try_from).map(NonZeroU32::new).unwrap_or(something);
There would be no undefined behavior in the new version.
Metadata
Metadata
Assignees
Labels
No labels