From 31cd2cbac1f9219b0d9d9511e0b06055aaf23358 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: Mon, 27 May 2024 15:56:04 +0300 Subject: [PATCH 1/2] Tweak `util_libc::open_readonly` --- src/use_file.rs | 6 +++--- src/util_libc.rs | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/use_file.rs b/src/use_file.rs index d2fe244f2..9167445eb 100644 --- a/src/use_file.rs +++ b/src/use_file.rs @@ -16,7 +16,7 @@ use core::{ /// - On Redox, only /dev/urandom is provided. /// - On AIX, /dev/urandom will "provide cryptographically secure output". /// - On Haiku and QNX Neutrino they are identical. -const FILE_PATH: &str = "/dev/urandom\0"; +const FILE_PATH: &[u8] = b"/dev/urandom\0"; const FD_UNINIT: usize = usize::max_value(); pub fn getrandom_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { @@ -57,7 +57,7 @@ fn get_rng_fd() -> Result { #[cfg(any(target_os = "android", target_os = "linux"))] wait_until_rng_ready()?; - let fd = unsafe { open_readonly(FILE_PATH)? }; + let fd = open_readonly(FILE_PATH)?; // The fd always fits in a usize without conflicting with FD_UNINIT. debug_assert!(fd >= 0 && (fd as usize) < FD_UNINIT); FD.store(fd as usize, Relaxed); @@ -69,7 +69,7 @@ fn get_rng_fd() -> Result { #[cfg(any(target_os = "android", target_os = "linux"))] fn wait_until_rng_ready() -> Result<(), Error> { // Poll /dev/random to make sure it is ok to read from /dev/urandom. - let fd = unsafe { open_readonly("/dev/random\0")? }; + let fd = open_readonly(b"/dev/random\0")?; let mut pfd = libc::pollfd { fd, events: libc::POLLIN, diff --git a/src/util_libc.rs b/src/util_libc.rs index 1d6bf9a2c..a644d23b7 100644 --- a/src/util_libc.rs +++ b/src/util_libc.rs @@ -70,14 +70,20 @@ pub fn sys_fill_exact( Ok(()) } -// SAFETY: path must be null terminated, FD must be manually closed. -pub unsafe fn open_readonly(path: &str) -> Result { - debug_assert_eq!(path.as_bytes().last(), Some(&0)); +/// Open a file in read-only mode. +/// +/// # Panics +/// If `path` does not contain any zeros. +#[inline(always)] +pub fn open_readonly(path: &[u8]) -> Result { + assert!(path.iter().any(|&b| b == 0)); loop { - let fd = libc::open( - path.as_ptr().cast::(), - libc::O_RDONLY | libc::O_CLOEXEC, - ); + let fd = unsafe { + libc::open( + path.as_ptr().cast::(), + libc::O_RDONLY | libc::O_CLOEXEC, + ) + }; if fd >= 0 { return Ok(fd); } From 3d47b86fcf1556fc1149f5fe91701e946daceddb Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 29 May 2024 15:23:23 +0300 Subject: [PATCH 2/2] Add TODO note --- src/util_libc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util_libc.rs b/src/util_libc.rs index a644d23b7..add966dea 100644 --- a/src/util_libc.rs +++ b/src/util_libc.rs @@ -74,6 +74,8 @@ pub fn sys_fill_exact( /// /// # Panics /// If `path` does not contain any zeros. +// TODO: Move `path` to `CStr` and use `CStr::from_bytes_until_nul` (MSRV 1.69) +// or C-string literals (MSRV 1.77) for statics #[inline(always)] pub fn open_readonly(path: &[u8]) -> Result { assert!(path.iter().any(|&b| b == 0));