| extern"C"{ |
| fnsys_read_entropy(buffer:*mutu8,length:usize,flags:u32) -> isize; |
| } |
| |
| while !dest.is_empty(){ |
| let res = unsafe{sys_read_entropy(dest.as_mut_ptr()as*mutu8, 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)asu32)}; |
| returnErr(code.into()); |
| } |
- If
res == -sizie::MIN then (-res) will overflow. To fix, use checked_neg(). - if
res < (i32::MIN as isize) then (-res) as u32 is a truncating, i.e. lossy conversion. To fix: avoid using as for integer conversions and instead use TryInto for this conversion. - if
(-res) % 0x1_0000_0000 == 0 then (-res) as u32 is zero and then NonZeroU32::new_unchecked((-res) as u32) is undefined behavior. To fix, use the safe NonZerou32::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.
getrandom/src/hermit.rs
Lines 4 to 7 in 35808a4
getrandom/src/hermit.rs
Lines 9 to 16 in 35808a4
res == -sizie::MINthen(-res)will overflow. To fix, usechecked_neg().res < (i32::MIN as isize)then(-res) as u32is a truncating, i.e. lossy conversion. To fix: avoid usingasfor integer conversions and instead useTryIntofor this conversion.(-res) % 0x1_0000_0000 == 0then(-res) as u32is 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:
There would be no undefined behavior in the new version.