Skip to content

Commit b75db5c

Browse files
authored
linux_android_with_fallback: do not use dlsym on MUSL targets (#602)
1 parent 3ba857b commit b75db5c

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

src/backends/linux_android_with_fallback.rs

+20-10
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use super::use_file;
33
use crate::Error;
44
use core::{
55
ffi::c_void,
6-
mem::{self, MaybeUninit},
7-
ptr::{self, NonNull},
6+
mem::{transmute, MaybeUninit},
7+
ptr::NonNull,
88
sync::atomic::{AtomicPtr, Ordering},
99
};
1010
use use_file::util_libc;
@@ -17,18 +17,28 @@ type GetRandomFn = unsafe extern "C" fn(*mut c_void, libc::size_t, libc::c_uint)
1717
/// or not supported by kernel.
1818
const NOT_AVAILABLE: NonNull<c_void> = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) };
1919

20-
static GETRANDOM_FN: AtomicPtr<c_void> = AtomicPtr::new(ptr::null_mut());
20+
static GETRANDOM_FN: AtomicPtr<c_void> = AtomicPtr::new(core::ptr::null_mut());
2121

2222
#[cold]
2323
#[inline(never)]
2424
fn init() -> NonNull<c_void> {
25-
static NAME: &[u8] = b"getrandom\0";
26-
let name_ptr = NAME.as_ptr().cast::<libc::c_char>();
27-
let raw_ptr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) };
25+
// Use static linking to `libc::getrandom` on MUSL targets and `dlsym` everywhere else
26+
#[cfg(not(target_env = "musl"))]
27+
let raw_ptr = {
28+
static NAME: &[u8] = b"getrandom\0";
29+
let name_ptr = NAME.as_ptr().cast::<libc::c_char>();
30+
unsafe { libc::dlsym(libc::RTLD_DEFAULT, name_ptr) }
31+
};
32+
#[cfg(target_env = "musl")]
33+
let raw_ptr = {
34+
let fptr: GetRandomFn = libc::getrandom;
35+
unsafe { transmute::<GetRandomFn, *mut c_void>(fptr) }
36+
};
37+
2838
let res_ptr = match NonNull::new(raw_ptr) {
2939
Some(fptr) => {
30-
let getrandom_fn = unsafe { mem::transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
31-
let dangling_ptr = ptr::NonNull::dangling().as_ptr();
40+
let getrandom_fn = unsafe { transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
41+
let dangling_ptr = NonNull::dangling().as_ptr();
3242
// Check that `getrandom` syscall is supported by kernel
3343
let res = unsafe { getrandom_fn(dangling_ptr, 0, 0) };
3444
if cfg!(getrandom_test_linux_fallback) {
@@ -54,7 +64,7 @@ fn init() -> NonNull<c_void> {
5464
res_ptr
5565
}
5666

57-
// prevent inlining of the fallback implementation
67+
// Prevent inlining of the fallback implementation
5868
#[inline(never)]
5969
fn use_file_fallback(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
6070
use_file::fill_inner(dest)
@@ -78,7 +88,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
7888
use_file_fallback(dest)
7989
} else {
8090
// note: `transmute` is currently the only way to convert a pointer into a function reference
81-
let getrandom_fn = unsafe { mem::transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
91+
let getrandom_fn = unsafe { transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
8292
util_libc::sys_fill_exact(dest, |buf| unsafe {
8393
getrandom_fn(buf.as_mut_ptr().cast(), buf.len(), 0)
8494
})

0 commit comments

Comments
 (0)