From 70b09d7c79fbd61817cde0ce827cfbc81bf64b5d Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Tue, 17 Feb 2026 12:44:22 -0800 Subject: [PATCH] Avoid accessing `errno` on unexpected return values. We expect that these system calls will never return anything other than 0 or -1 but if they do for some reason, then we shouldn't access `errno`. --- CHANGELOG.md | 2 ++ src/backends/getentropy.rs | 17 +++++++++++++---- src/backends/vxworks.rs | 10 +++++++--- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a2a2401d..30fc31713 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump `r-efi` dependency to v6 [#814] ### Fixed +- Read `errno` only when it is set [#810] - Check the return value of `ProcessPrng` on Windows [#811] [Unreleased]: https://github.com/rust-random/getrandom/compare/v0.4.1...master +[#810]: https://github.com/rust-random/getrandom/pull/810 [#811]: https://github.com/rust-random/getrandom/pull/811 [#814]: https://github.com/rust-random/getrandom/pull/814 diff --git a/src/backends/getentropy.rs b/src/backends/getentropy.rs index 463c463be..09921c973 100644 --- a/src/backends/getentropy.rs +++ b/src/backends/getentropy.rs @@ -1,5 +1,9 @@ //! Implementation using getentropy(2) //! +//! When porting to a new target, ensure that its implementation follows the +//! POSIX conventions from +//! . +//! //! Available since: //! - macOS 10.12 //! - OpenBSD 5.6 @@ -17,11 +21,16 @@ mod utils; #[inline] pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - for chunk in dest.chunks_mut(256) { + // https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/limits.h.html + // says `GETENTROPY_MAX` is at least 256. + const GETENTROPY_MAX: usize = 256; + + for chunk in dest.chunks_mut(GETENTROPY_MAX) { let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::(), chunk.len()) }; - if ret != 0 { - let errno = utils::get_errno(); - return Err(Error::from_errno(errno)); + match ret { + 0 => continue, + -1 => return Err(Error::from_errno(utils::get_errno())), + _ => return Err(Error::UNEXPECTED), } } Ok(()) diff --git a/src/backends/vxworks.rs b/src/backends/vxworks.rs index 10d2e81be..aa07246ba 100644 --- a/src/backends/vxworks.rs +++ b/src/backends/vxworks.rs @@ -38,9 +38,13 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { .expect("chunk size is bounded by i32::MAX"); let p: *mut libc::c_uchar = chunk.as_mut_ptr().cast(); let ret = unsafe { libc::randABytes(p, chunk_len) }; - if ret != 0 { - let errno = unsafe { libc::errnoGet() }; - return Err(Error::from_errno(errno)); + match ret { + 0 => continue, + -1 => { + let errno = unsafe { libc::errnoGet() }; + return Err(Error::from_errno(errno)); + } + _ => return Err(Error::UNEXPECTED), } } Ok(())