From 6b2c9e00fb6575d3a04a63987ae365a3e405bb35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 10 Dec 2025 16:12:50 +0300 Subject: [PATCH 1/6] Refactor `util_libc` --- src/backends.rs | 6 -- src/backends/getentropy.rs | 7 +- src/backends/getrandom.rs | 15 +--- src/backends/linux_android_with_fallback.rs | 16 ++-- src/backends/linux_raw.rs | 8 +- src/backends/netbsd.rs | 6 +- src/backends/rdrand.rs | 2 +- src/backends/rndr.rs | 2 +- src/backends/solaris.rs | 9 ++- src/backends/use_file.rs | 24 +++--- src/backends/vxworks.rs | 6 +- src/error.rs | 13 ++++ src/util_libc.rs | 81 --------------------- src/utils/get_errno.rs | 29 ++++++++ src/{ => utils}/lazy.rs | 0 src/{backends => utils}/sanitizer.rs | 29 +------- src/utils/sys_fill_exact.rs | 36 +++++++++ 17 files changed, 124 insertions(+), 165 deletions(-) delete mode 100644 src/util_libc.rs create mode 100644 src/utils/get_errno.rs rename src/{ => utils}/lazy.rs (100%) rename src/{backends => utils}/sanitizer.rs (50%) create mode 100644 src/utils/sys_fill_exact.rs diff --git a/src/backends.rs b/src/backends.rs index 991d413b5..e572b8b5e 100644 --- a/src/backends.rs +++ b/src/backends.rs @@ -13,11 +13,9 @@ cfg_if! { pub use custom::*; } else if #[cfg(getrandom_backend = "linux_getrandom")] { mod getrandom; - mod sanitizer; pub use getrandom::*; } else if #[cfg(getrandom_backend = "linux_raw")] { mod linux_raw; - mod sanitizer; pub use linux_raw::*; } else if #[cfg(getrandom_backend = "rdrand")] { mod rdrand; @@ -49,7 +47,6 @@ cfg_if! { pub use unsupported::*; } else if #[cfg(all(target_os = "linux", target_env = ""))] { mod linux_raw; - mod sanitizer; pub use linux_raw::*; } else if #[cfg(target_os = "espidf")] { mod esp_idf; @@ -117,7 +114,6 @@ cfg_if! { ))] { mod use_file; mod linux_android_with_fallback; - mod sanitizer; pub use linux_android_with_fallback::*; } else if #[cfg(any( target_os = "android", @@ -132,8 +128,6 @@ cfg_if! { all(target_os = "horizon", target_arch = "arm"), ))] { mod getrandom; - #[cfg(any(target_os = "android", target_os = "linux"))] - mod sanitizer; pub use getrandom::*; } else if #[cfg(target_os = "solaris")] { mod solaris; diff --git a/src/backends/getentropy.rs b/src/backends/getentropy.rs index ed181f019..463c463be 100644 --- a/src/backends/getentropy.rs +++ b/src/backends/getentropy.rs @@ -12,15 +12,16 @@ use core::{ffi::c_void, mem::MaybeUninit}; pub use crate::util::{inner_u32, inner_u64}; -#[path = "../util_libc.rs"] -mod util_libc; +#[path = "../utils/get_errno.rs"] +mod utils; #[inline] pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { for chunk in dest.chunks_mut(256) { let ret = unsafe { libc::getentropy(chunk.as_mut_ptr().cast::(), chunk.len()) }; if ret != 0 { - return Err(util_libc::last_os_error()); + let errno = utils::get_errno(); + return Err(Error::from_errno(errno)); } } Ok(()) diff --git a/src/backends/getrandom.rs b/src/backends/getrandom.rs index af97eab28..927dc85c5 100644 --- a/src/backends/getrandom.rs +++ b/src/backends/getrandom.rs @@ -20,19 +20,12 @@ use core::mem::MaybeUninit; pub use crate::util::{inner_u32, inner_u64}; -#[path = "../util_libc.rs"] -mod util_libc; +#[path = "../utils/sys_fill_exact.rs"] +mod utils; #[inline] pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { - util_libc::sys_fill_exact(dest, |buf| { - let ret = unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }; - - #[cfg(any(target_os = "android", target_os = "linux"))] - unsafe { - super::sanitizer::unpoison_linux_getrandom_result(buf, ret); - } - - ret + utils::sys_fill_exact(dest, |buf| unsafe { + libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }) } diff --git a/src/backends/linux_android_with_fallback.rs b/src/backends/linux_android_with_fallback.rs index d4ae6f247..48ce62886 100644 --- a/src/backends/linux_android_with_fallback.rs +++ b/src/backends/linux_android_with_fallback.rs @@ -1,5 +1,5 @@ //! Implementation for Linux / Android with `/dev/urandom` fallback -use super::{sanitizer, use_file}; +use super::use_file; use crate::Error; use core::{ ffi::c_void, @@ -7,7 +7,7 @@ use core::{ ptr::NonNull, sync::atomic::{AtomicPtr, Ordering}, }; -use use_file::util_libc; +use use_file::utils; pub use crate::util::{inner_u32, inner_u64}; @@ -44,13 +44,13 @@ fn init() -> NonNull { if cfg!(getrandom_test_linux_fallback) { NOT_AVAILABLE } else if res.is_negative() { - match util_libc::last_os_error().raw_os_error() { - Some(libc::ENOSYS) => NOT_AVAILABLE, // No kernel support + match utils::get_errno() { + libc::ENOSYS => NOT_AVAILABLE, // No kernel support // The fallback on EPERM is intentionally not done on Android since this workaround // seems to be needed only for specific Linux-based products that aren't based // on Android. See https://github.com/rust-random/getrandom/issues/229. #[cfg(target_os = "linux")] - Some(libc::EPERM) => NOT_AVAILABLE, // Blocked by seccomp + libc::EPERM => NOT_AVAILABLE, // Blocked by seccomp _ => fptr, } } else { @@ -94,10 +94,8 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { } else { // note: `transmute` is currently the only way to convert a pointer into a function reference let getrandom_fn = unsafe { transmute::, GetRandomFn>(fptr) }; - util_libc::sys_fill_exact(dest, |buf| unsafe { - let ret = getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0); - sanitizer::unpoison_linux_getrandom_result(buf, ret); - ret + utils::sys_fill_exact(dest, |buf| unsafe { + getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0) }) } } diff --git a/src/backends/linux_raw.rs b/src/backends/linux_raw.rs index aec160f3f..9d9af238f 100644 --- a/src/backends/linux_raw.rs +++ b/src/backends/linux_raw.rs @@ -6,6 +6,9 @@ use crate::{Error, MaybeUninit}; #[cfg(not(any(target_os = "android", target_os = "linux")))] compile_error!("`linux_raw` backend can be enabled only for Linux/Android targets!"); +#[path = "../utils/sanitizer.rs"] +mod utils; + #[allow(non_upper_case_globals)] unsafe fn getrandom_syscall(buf: *mut u8, buflen: usize, flags: u32) -> isize { let r0; @@ -147,11 +150,12 @@ pub fn fill_inner(mut dest: &mut [MaybeUninit]) -> Result<(), Error> { loop { let ret = unsafe { getrandom_syscall(dest.as_mut_ptr().cast(), dest.len(), 0) }; - unsafe { sanitizer::unpoison_linux_getrandom_result(dest, ret) }; match usize::try_from(ret) { Ok(0) => return Err(Error::UNEXPECTED), Ok(len) => { - dest = dest.get_mut(len..).ok_or(Error::UNEXPECTED)?; + let (l, r) = dest.split_at_mut_checked(len).ok_or(Error::UNEXPECTED)?; + unsafe { utils::unpoison(l) }; + dest = r; if dest.is_empty() { return Ok(()); } diff --git a/src/backends/netbsd.rs b/src/backends/netbsd.rs index f228a8b13..0da0d492c 100644 --- a/src/backends/netbsd.rs +++ b/src/backends/netbsd.rs @@ -14,8 +14,8 @@ use core::{ pub use crate::util::{inner_u32, inner_u64}; -#[path = "../util_libc.rs"] -mod util_libc; +#[path = "../utils/sys_fill_exact.rs"] +mod utils; unsafe extern "C" fn polyfill_using_kern_arand( buf: *mut c_void, @@ -72,7 +72,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { fptr = init(); } let fptr = unsafe { mem::transmute::<*mut c_void, GetRandomFn>(fptr) }; - util_libc::sys_fill_exact(dest, |buf| unsafe { + utils::sys_fill_exact(dest, |buf| unsafe { fptr(buf.as_mut_ptr().cast::(), buf.len(), 0) }) } diff --git a/src/backends/rdrand.rs b/src/backends/rdrand.rs index ece9a434d..cf617b36c 100644 --- a/src/backends/rdrand.rs +++ b/src/backends/rdrand.rs @@ -2,7 +2,7 @@ use crate::{Error, util::slice_as_uninit}; use core::mem::{MaybeUninit, size_of}; -#[path = "../lazy.rs"] +#[path = "../utils/lazy.rs"] mod lazy; #[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] diff --git a/src/backends/rndr.rs b/src/backends/rndr.rs index 0b0636aea..1a24b49f7 100644 --- a/src/backends/rndr.rs +++ b/src/backends/rndr.rs @@ -69,7 +69,7 @@ fn is_rndr_available() -> bool { #[cfg(not(target_feature = "rand"))] fn is_rndr_available() -> bool { - #[path = "../lazy.rs"] + #[path = "../utils/lazy.rs"] mod lazy; static RNDR_GOOD: lazy::LazyBool = lazy::LazyBool::new(); diff --git a/src/backends/solaris.rs b/src/backends/solaris.rs index c27f91a5f..f3e22de05 100644 --- a/src/backends/solaris.rs +++ b/src/backends/solaris.rs @@ -14,12 +14,10 @@ //! which also explains why this crate should not use getentropy(2). use crate::Error; use core::{ffi::c_void, mem::MaybeUninit}; +use libc::___errno as errno_location; pub use crate::util::{inner_u32, inner_u64}; -#[path = "../util_libc.rs"] -mod util_libc; - const MAX_BYTES: usize = 1024; #[inline] @@ -33,7 +31,10 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { // Good. Keep going. Ok(ret) if ret == chunk.len() => {} // The syscall failed. - Ok(0) => return Err(util_libc::last_os_error()), + Ok(0) => { + let errno = unsafe { core::ptr::read(errno_location()) }; + return Err(Error::from_errno(errno)); + } // All other cases should be impossible. _ => return Err(Error::UNEXPECTED), } diff --git a/src/backends/use_file.rs b/src/backends/use_file.rs index 796dbbc59..a1d372a04 100644 --- a/src/backends/use_file.rs +++ b/src/backends/use_file.rs @@ -9,8 +9,8 @@ use core::{ #[cfg(not(any(target_os = "android", target_os = "linux")))] pub use crate::util::{inner_u32, inner_u64}; -#[path = "../util_libc.rs"] -pub(super) mod util_libc; +#[path = "../utils/sys_fill_exact.rs"] +pub(super) mod utils; /// For all platforms, we use `/dev/urandom` rather than `/dev/random`. /// For more information see the linked man pages in lib.rs. @@ -46,7 +46,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { if fd == FD_UNINIT || fd == FD_ONGOING_INIT { fd = open_or_wait()?; } - util_libc::sys_fill_exact(dest, |buf| unsafe { + utils::sys_fill_exact(dest, |buf| unsafe { libc::read(fd, buf.as_mut_ptr().cast::(), buf.len()) }) } @@ -58,10 +58,10 @@ fn open_readonly(path: &CStr) -> Result { if fd >= 0 { return Ok(fd); } - let err = util_libc::last_os_error(); + let errno = utils::get_errno(); // We should try again if open() was interrupted. - if err.raw_os_error() != Some(libc::EINTR) { - return Err(err); + if errno != libc::EINTR { + return Err(Error::from_errno(errno)); } } } @@ -136,7 +136,7 @@ mod sync { #[cfg(any(target_os = "android", target_os = "linux"))] mod sync { - use super::{Error, FD, FD_ONGOING_INIT, open_readonly, util_libc::last_os_error}; + use super::{Error, FD, FD_ONGOING_INIT, open_readonly, utils}; /// Wait for atomic `FD` to change value from `FD_ONGOING_INIT` to something else. /// @@ -152,7 +152,7 @@ mod sync { debug_assert!({ match ret { 0 => true, - -1 => last_os_error().raw_os_error() == Some(libc::EAGAIN), + -1 => utils::get_errno() == libc::EAGAIN, _ => false, } }); @@ -209,12 +209,12 @@ mod sync { debug_assert_eq!(res, 1); break Ok(()); } - let err = last_os_error(); + let errno = utils::get_errno(); // Assuming that `poll` is called correctly, // on Linux it can return only EINTR and ENOMEM errors. - match err.raw_os_error() { - Some(libc::EINTR) => continue, - _ => break Err(err), + match errno { + libc::EINTR => continue, + _ => break Err(Error::from_errno(errno)), } }; unsafe { libc::close(fd) }; diff --git a/src/backends/vxworks.rs b/src/backends/vxworks.rs index 5f5e6773b..10d2e81be 100644 --- a/src/backends/vxworks.rs +++ b/src/backends/vxworks.rs @@ -6,9 +6,6 @@ use core::{ sync::atomic::{AtomicBool, Ordering::Relaxed}, }; -#[path = "../util_libc.rs"] -mod util_libc; - pub use crate::util::{inner_u32, inner_u64}; static RNG_INIT: AtomicBool = AtomicBool::new(false); @@ -42,7 +39,8 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { let p: *mut libc::c_uchar = chunk.as_mut_ptr().cast(); let ret = unsafe { libc::randABytes(p, chunk_len) }; if ret != 0 { - return Err(util_libc::last_os_error()); + let errno = unsafe { libc::errnoGet() }; + return Err(Error::from_errno(errno)); } } Ok(()) diff --git a/src/error.rs b/src/error.rs index 069d8c109..e2b980e63 100644 --- a/src/error.rs +++ b/src/error.rs @@ -57,6 +57,19 @@ impl Error { /// Custom errors can be in the range of 2^17..(2^17 + 2^16) const CUSTOM_START: RawOsError = 1 << 17; + /// Creates a new instance of an `Error` from a positive error code. + #[allow(dead_code)] + pub(super) fn from_errno(errno: i32) -> Self { + if errno > 0 { + let code = errno + .checked_neg() + .expect("Positive number can be always negated"); + Error::from_neg_error_code(code) + } else { + Error::ERRNO_NOT_POSITIVE + } + } + /// Creates a new instance of an `Error` from a negative error code. #[cfg(not(target_os = "uefi"))] #[allow(dead_code)] diff --git a/src/util_libc.rs b/src/util_libc.rs deleted file mode 100644 index 69432891c..000000000 --- a/src/util_libc.rs +++ /dev/null @@ -1,81 +0,0 @@ -use crate::Error; -use core::mem::MaybeUninit; - -cfg_if! { - if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "cygwin"))] { - use libc::__errno as errno_location; - } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox", target_os = "dragonfly"))] { - use libc::__errno_location as errno_location; - } else if #[cfg(any(target_os = "solaris", target_os = "illumos"))] { - use libc::___errno as errno_location; - } else if #[cfg(any(target_os = "macos", target_os = "freebsd"))] { - use libc::__error as errno_location; - } else if #[cfg(target_os = "haiku")] { - use libc::_errnop as errno_location; - } else if #[cfg(target_os = "nto")] { - use libc::__get_errno_ptr as errno_location; - } else if #[cfg(any(all(target_os = "horizon", target_arch = "arm"), target_os = "vita"))] { - unsafe extern "C" { - // Not provided by libc: https://github.com/rust-lang/libc/issues/1995 - fn __errno() -> *mut libc::c_int; - } - use __errno as errno_location; - } else if #[cfg(target_os = "aix")] { - use libc::_Errno as errno_location; - } -} - -cfg_if! { - if #[cfg(target_os = "vxworks")] { - use libc::errnoGet as get_errno; - } else { - unsafe fn get_errno() -> libc::c_int { unsafe { *errno_location() }} - } -} - -pub(crate) fn last_os_error() -> Error { - // We assume that on all targets which use the `util_libc` module `c_int` is equal to `i32` - let errno: i32 = unsafe { get_errno() }; - - if errno > 0 { - let code = errno - .checked_neg() - .expect("Positive number can be always negated"); - Error::from_neg_error_code(code) - } else { - Error::ERRNO_NOT_POSITIVE - } -} - -/// Fill a buffer by repeatedly invoking `sys_fill`. -/// -/// The `sys_fill` function: -/// - should return -1 and set errno on failure -/// - should return the number of bytes written on success -#[allow(dead_code)] -pub(crate) fn sys_fill_exact( - mut buf: &mut [MaybeUninit], - sys_fill: impl Fn(&mut [MaybeUninit]) -> libc::ssize_t, -) -> Result<(), Error> { - while !buf.is_empty() { - let res = sys_fill(buf); - match res { - res if res > 0 => { - let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?; - buf = buf.get_mut(len..).ok_or(Error::UNEXPECTED)?; - } - -1 => { - let err = last_os_error(); - // We should try again if the call was interrupted. - if err.raw_os_error() != Some(libc::EINTR) { - return Err(err); - } - } - // Negative return codes not equal to -1 should be impossible. - // EOF (ret = 0) should be impossible, as the data we are reading - // should be an infinite stream of random bytes. - _ => return Err(Error::UNEXPECTED), - } - } - Ok(()) -} diff --git a/src/utils/get_errno.rs b/src/utils/get_errno.rs new file mode 100644 index 000000000..1895fc05e --- /dev/null +++ b/src/utils/get_errno.rs @@ -0,0 +1,29 @@ +cfg_if! { + if #[cfg(any(target_os = "netbsd", target_os = "openbsd", target_os = "android", target_os = "cygwin"))] { + use libc::__errno as errno_location; + } else if #[cfg(any(target_os = "linux", target_os = "emscripten", target_os = "hurd", target_os = "redox", target_os = "dragonfly"))] { + use libc::__errno_location as errno_location; + } else if #[cfg(target_os = "illumos")] { + use libc::___errno as errno_location; + } else if #[cfg(any(target_os = "macos", target_os = "freebsd"))] { + use libc::__error as errno_location; + } else if #[cfg(target_os = "haiku")] { + use libc::_errnop as errno_location; + } else if #[cfg(target_os = "nto")] { + use libc::__get_errno_ptr as errno_location; + } else if #[cfg(any(all(target_os = "horizon", target_arch = "arm"), target_os = "vita"))] { + unsafe extern "C" { + // Not provided by libc: https://github.com/rust-lang/libc/issues/1995 + fn __errno() -> *mut libc::c_int; + } + use __errno as errno_location; + } else if #[cfg(target_os = "aix")] { + use libc::_Errno as errno_location; + } else { + compile_error!("errno_location is not provided for the target"); + } +} + +pub(crate) fn get_errno() -> libc::c_int { + unsafe { core::ptr::read(errno_location()) } +} diff --git a/src/lazy.rs b/src/utils/lazy.rs similarity index 100% rename from src/lazy.rs rename to src/utils/lazy.rs diff --git a/src/backends/sanitizer.rs b/src/utils/sanitizer.rs similarity index 50% rename from src/backends/sanitizer.rs rename to src/utils/sanitizer.rs index 5dd193492..205dc94a5 100644 --- a/src/backends/sanitizer.rs +++ b/src/utils/sanitizer.rs @@ -20,36 +20,9 @@ pub unsafe fn unpoison(buf: &mut [MaybeUninit]) { } let a = buf.as_mut_ptr().cast(); let size = buf.len(); - unsafe { - __msan_unpoison(a, size); - } + unsafe { __msan_unpoison(a, size) }; } else { let _ = buf; } } } - -/// Interprets the result of the `getrandom` syscall of Linux, unpoisoning any -/// written part of `buf`. -/// -/// `buf` must be the output buffer that was originally passed to the `getrandom` -/// syscall. -/// -/// `ret` must be the result returned by `getrandom`. If `ret` is negative or -/// larger than the length of `buf` then nothing is done. -/// -/// Memory Sanitizer only intercepts `getrandom` on this condition (from its -/// source code): -/// ```c -/// #define SANITIZER_INTERCEPT_GETRANDOM \ -/// ((SI_LINUX && __GLIBC_PREREQ(2, 25)) || SI_FREEBSD || SI_SOLARIS) -/// ``` -/// So, effectively, we have to assume that it is never intercepted on Linux. -#[cfg(any(target_os = "android", target_os = "linux"))] -pub unsafe fn unpoison_linux_getrandom_result(buf: &mut [MaybeUninit], ret: isize) { - if let Ok(bytes_written) = usize::try_from(ret) { - if let Some(written) = buf.get_mut(..bytes_written) { - unsafe { unpoison(written) } - } - } -} diff --git a/src/utils/sys_fill_exact.rs b/src/utils/sys_fill_exact.rs new file mode 100644 index 000000000..c57df04fb --- /dev/null +++ b/src/utils/sys_fill_exact.rs @@ -0,0 +1,36 @@ +use crate::Error; +use core::mem::MaybeUninit; + +mod get_errno; +mod sanitizer; + +pub(crate) use get_errno::get_errno; + +pub(crate) fn sys_fill_exact( + mut buf: &mut [MaybeUninit], + sys_fill: impl Fn(&mut [MaybeUninit]) -> libc::ssize_t, +) -> Result<(), Error> { + while !buf.is_empty() { + let res = sys_fill(buf); + match res { + res if res > 0 => { + let len = usize::try_from(res).map_err(|_| Error::UNEXPECTED)?; + let (l, r) = buf.split_at_mut_checked(len).ok_or(Error::UNEXPECTED)?; + unsafe { sanitizer::unpoison(l) }; + buf = r; + } + -1 => { + let errno = get_errno(); + // We should try again if the call was interrupted. + if errno != libc::EINTR { + return Err(Error::from_errno(errno)); + } + } + // Negative return codes not equal to -1 should be impossible. + // EOF (ret = 0) should be impossible, as the data we are reading + // should be an infinite stream of random bytes. + _ => return Err(Error::UNEXPECTED), + } + } + Ok(()) +} From 81f8439a5a2763595468407f9917df5f81aaa241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 10 Dec 2025 16:17:59 +0300 Subject: [PATCH 2/6] fix `linux_raw` --- src/backends/linux_raw.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/linux_raw.rs b/src/backends/linux_raw.rs index 9d9af238f..31cddfc8a 100644 --- a/src/backends/linux_raw.rs +++ b/src/backends/linux_raw.rs @@ -1,5 +1,4 @@ //! Implementation for Linux / Android using `asm!`-based syscalls. -use super::sanitizer; pub use crate::util::{inner_u32, inner_u64}; use crate::{Error, MaybeUninit}; From a3bbbf11c94f6708d27cdba2fa50317c3fb19839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 10 Dec 2025 16:25:26 +0300 Subject: [PATCH 3/6] fix uefi --- src/error.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/error.rs b/src/error.rs index e2b980e63..6e6725caf 100644 --- a/src/error.rs +++ b/src/error.rs @@ -58,6 +58,7 @@ impl Error { const CUSTOM_START: RawOsError = 1 << 17; /// Creates a new instance of an `Error` from a positive error code. + #[cfg(not(target_os = "uefi"))] #[allow(dead_code)] pub(super) fn from_errno(errno: i32) -> Self { if errno > 0 { From 04bf1ab3ef1d1f401440d961c461f1e26e288ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Wed, 10 Dec 2025 16:44:50 +0300 Subject: [PATCH 4/6] tweak docs --- src/error.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/error.rs b/src/error.rs index 6e6725caf..7708959ca 100644 --- a/src/error.rs +++ b/src/error.rs @@ -57,7 +57,9 @@ impl Error { /// Custom errors can be in the range of 2^17..(2^17 + 2^16) const CUSTOM_START: RawOsError = 1 << 17; - /// Creates a new instance of an `Error` from a positive error code. + /// Creates a new `Error` instance from a positive error code. + /// + /// Returns [`Error::ERRNO_NOT_POSITIVE`] for zero and negative error codes. #[cfg(not(target_os = "uefi"))] #[allow(dead_code)] pub(super) fn from_errno(errno: i32) -> Self { @@ -71,7 +73,9 @@ impl Error { } } - /// Creates a new instance of an `Error` from a negative error code. + /// Creates a new `Error` instance from a negative error code. + /// + /// Returns [`Error::UNEXPECTED`] for zero and positive error codes. #[cfg(not(target_os = "uefi"))] #[allow(dead_code)] pub(super) fn from_neg_error_code(code: RawOsError) -> Self { From 8f3e8cbeeb2a9542bcde2286ad3289023a11737d Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Sat, 27 Dec 2025 19:52:53 +0300 Subject: [PATCH 5/6] return `sys_fill_exact` docs --- src/utils/sys_fill_exact.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/utils/sys_fill_exact.rs b/src/utils/sys_fill_exact.rs index c57df04fb..13d7a386a 100644 --- a/src/utils/sys_fill_exact.rs +++ b/src/utils/sys_fill_exact.rs @@ -6,6 +6,11 @@ mod sanitizer; pub(crate) use get_errno::get_errno; +/// Fill a buffer by repeatedly invoking `sys_fill`. +/// +/// The `sys_fill` function: +/// - should return -1 and set errno on failure +/// - should return the number of bytes written on success pub(crate) fn sys_fill_exact( mut buf: &mut [MaybeUninit], sys_fill: impl Fn(&mut [MaybeUninit]) -> libc::ssize_t, From c3f0ec4d79b24ac6fb01ff8c1a5359e4286d76b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Sat, 27 Dec 2025 19:56:22 +0300 Subject: [PATCH 6/6] Update Cargo.lock --- Cargo.lock | 190 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 150 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 057dcb187..2aa69be32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,17 +2,40 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + [[package]] name = "bumpalo" version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" -version = "1.2.50" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "shlex", @@ -26,9 +49,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "getrandom" @@ -44,11 +67,17 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + [[package]] name = "js-sys" -version = "0.3.80" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -61,10 +90,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] -name = "log" -version = "0.4.29" +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "memchr" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "minicov" @@ -76,12 +111,37 @@ dependencies = [ "walkdir", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + [[package]] name = "proc-macro2" version = "1.0.103" @@ -112,6 +172,12 @@ version = "0.10.0-rc-3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "same-file" version = "1.0.6" @@ -121,6 +187,49 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + [[package]] name = "shlex" version = "1.3.0" @@ -165,35 +274,22 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.103" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-futures" -version = "0.4.53" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b221ff421256839509adbb55998214a70d829d3a28c69b4a6672e9d2a42f67" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -204,9 +300,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.103" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -214,34 +310,42 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.103" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.103" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.53" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aee0a0f5343de9221a0d233b04520ed8dc2e6728dce180b1dcd9288ec9d9fa3c" +checksum = "25e90e66d265d3a1efc0e72a54809ab90b9c0c515915c67cdf658689d2c22c6c" dependencies = [ + "async-trait", + "cast", "js-sys", + "libm", "minicov", + "nu-ansi-term", + "num-traits", + "oorandom", + "serde", + "serde_json", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test-macro", @@ -249,9 +353,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.53" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a369369e4360c2884c3168d22bded735c43cccae97bbc147586d4b480edd138d" +checksum = "7150335716dce6028bead2b848e72f47b45e7b9422f64cccdc23bedca89affc1" dependencies = [ "proc-macro2", "quote", @@ -260,9 +364,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.80" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -297,3 +401,9 @@ name = "wit-bindgen" version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zmij" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d6085d62852e35540689d1f97ad663e3971fc19cf5eceab364d62c646ea167"