From 5c469368a22d98d70de1ac349c643100280274be 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, 5 Feb 2025 14:45:02 +0300 Subject: [PATCH 1/3] linux_android_with_fallback: do not use dlsym on MUSL targets --- src/backends/linux_android_with_fallback.rs | 30 ++++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/backends/linux_android_with_fallback.rs b/src/backends/linux_android_with_fallback.rs index 33dabd2e..379237c6 100644 --- a/src/backends/linux_android_with_fallback.rs +++ b/src/backends/linux_android_with_fallback.rs @@ -3,8 +3,8 @@ use super::use_file; use crate::Error; use core::{ ffi::c_void, - mem::{self, MaybeUninit}, - ptr::{self, NonNull}, + mem::{transmute, MaybeUninit}, + ptr::NonNull, sync::atomic::{AtomicPtr, Ordering}, }; use use_file::util_libc; @@ -17,18 +17,28 @@ type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint) /// or not supported by kernel. const NOT_AVAILABLE: NonNull = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) }; -static GETRANDOM_FN: AtomicPtr = AtomicPtr::new(ptr::null_mut()); +static GETRANDOM_FN: AtomicPtr = AtomicPtr::new(core::ptr::null_mut()); #[cold] #[inline(never)] fn init() -> NonNull { - static NAME: &[u8] = b"getrandom\0"; - let name_ptr = NAME.as_ptr().cast::(); - let raw_ptr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) }; + // Use static linking to `libc::getrandom` on MUSL targets and `dlsym` everywhere else + #[cfg(not(target_env = "musl"))] + let raw_ptr = { + static NAME: &[u8] = b"getrandom\0"; + let name_ptr = NAME.as_ptr().cast::(); + unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) } + }; + #[cfg(target_env = "musl")] + let raw_ptr = { + let fptr: GetRandomFn = libc::getrandom; + unsafe { transmute::(fptr) } + }; + let res_ptr = match NonNull::new(raw_ptr) { Some(fptr) => { - let getrandom_fn = unsafe { mem::transmute::, GetRandomFn>(fptr) }; - let dangling_ptr = ptr::NonNull::dangling().as_ptr(); + let getrandom_fn = unsafe { transmute::, GetRandomFn>(fptr) }; + let dangling_ptr = NonNull::dangling().as_ptr(); // Check that `getrandom` syscall is supported by kernel let res = unsafe { getrandom_fn(dangling_ptr, 0, 0) }; if cfg!(getrandom_test_linux_fallback) { @@ -54,7 +64,7 @@ fn init() -> NonNull { res_ptr } -// prevent inlining of the fallback implementation +// Prevent inlining of the fallback implementation #[inline(never)] fn use_file_fallback(dest: &mut [MaybeUninit]) -> Result<(), Error> { use_file::fill_inner(dest) @@ -78,7 +88,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { use_file_fallback(dest) } else { // note: `transmute` is currently the only way to convert a pointer into a function reference - let getrandom_fn = unsafe { mem::transmute::, GetRandomFn>(fptr) }; + let getrandom_fn = unsafe { transmute::, GetRandomFn>(fptr) }; util_libc::sys_fill_exact(dest, |buf| unsafe { getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0) }) From 60f2393f6187015ab0afe8d4a558900272824b8b 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, 5 Feb 2025 15:44:23 +0300 Subject: [PATCH 2/3] Add `#[cold]` to `use_file_fallback` --- src/backends/linux_android_with_fallback.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/linux_android_with_fallback.rs b/src/backends/linux_android_with_fallback.rs index 379237c6..54a08b50 100644 --- a/src/backends/linux_android_with_fallback.rs +++ b/src/backends/linux_android_with_fallback.rs @@ -65,6 +65,7 @@ fn init() -> NonNull { } // Prevent inlining of the fallback implementation +#[cold] #[inline(never)] fn use_file_fallback(dest: &mut [MaybeUninit]) -> Result<(), Error> { use_file::fill_inner(dest) From 3f2d0e599d2deeb7ddf63d425d8d3575627fbdba Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Wed, 5 Feb 2025 19:34:27 +0300 Subject: [PATCH 3/3] Revert addition of `#[cold]` --- src/backends/linux_android_with_fallback.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/linux_android_with_fallback.rs b/src/backends/linux_android_with_fallback.rs index 54a08b50..379237c6 100644 --- a/src/backends/linux_android_with_fallback.rs +++ b/src/backends/linux_android_with_fallback.rs @@ -65,7 +65,6 @@ fn init() -> NonNull { } // Prevent inlining of the fallback implementation -#[cold] #[inline(never)] fn use_file_fallback(dest: &mut [MaybeUninit]) -> Result<(), Error> { use_file::fill_inner(dest)