Skip to content

Commit c59f38e

Browse files
committed
Improve memory safety of Weak::new().
Do null terminator checking more completely and at compile time.
1 parent 7a79a6d commit c59f38e

File tree

2 files changed

+6
-7
lines changed

2 files changed

+6
-7
lines changed

src/netbsd.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ type GetRandomFn = unsafe extern "C" fn(*mut u8, libc::size_t, libc::c_uint) ->
2929

3030
pub fn getrandom_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
3131
// getrandom(2) was introduced in NetBSD 10.0
32-
static GETRANDOM: Weak = unsafe { Weak::new("getrandom\0") };
32+
static GETRANDOM_NAME: cstr::Ref = cstr::unwrap_const_from_bytes_with_nul(b"getrandom\0");
33+
static GETRANDOM: Weak = Weak::new(GETRANDOM_NAME);
3334
if let Some(fptr) = GETRANDOM.ptr() {
3435
let func: GetRandomFn = unsafe { core::mem::transmute(fptr) };
3536
return sys_fill_exact(dest, |buf| unsafe {

src/util_libc.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ pub fn sys_fill_exact(
8585
// https://github.com/rust-lang/rust/blob/1.61.0/library/std/src/sys/unix/weak.rs#L84
8686
// except that the caller must manually cast self.ptr() to a function pointer.
8787
pub struct Weak {
88-
name: &'static str,
88+
name: cstr::Ref,
8989
addr: AtomicPtr<c_void>,
9090
}
9191

@@ -98,9 +98,8 @@ impl Weak {
9898
// TODO: Replace with core::ptr::invalid_mut(1) when that is stable.
9999
const UNINIT: *mut c_void = 1 as *mut c_void;
100100

101-
// Construct a binding to a C function with a given name. This function is
102-
// unsafe because `name` _must_ be null terminated.
103-
pub const unsafe fn new(name: &'static str) -> Self {
101+
// Construct a binding to a C function with a given name.
102+
pub const fn new(name: cstr::Ref) -> Self {
104103
Self {
105104
name,
106105
addr: AtomicPtr::new(Self::UNINIT),
@@ -120,8 +119,7 @@ impl Weak {
120119
// the use of non-Relaxed operations is probably unnecessary.
121120
match self.addr.load(Ordering::Relaxed) {
122121
Self::UNINIT => {
123-
// XXX/FIXME: Unchecked UTF-8-to-c_char cast.
124-
let symbol = self.name.as_ptr().cast::<libc::c_char>();
122+
let symbol = self.name.as_ptr();
125123
let addr = unsafe { libc::dlsym(libc::RTLD_DEFAULT, symbol) };
126124
// Synchronizes with the Acquire fence below
127125
self.addr.store(addr, Ordering::Release);

0 commit comments

Comments
 (0)