diff --git a/src/synch/futex.rs b/src/synch/futex.rs index ded2428357..26ffa32f8c 100644 --- a/src/synch/futex.rs +++ b/src/synch/futex.rs @@ -167,13 +167,15 @@ pub(crate) fn futex_wait_and_set( /// Wake `count` threads waiting on the futex at address. Returns the number of threads /// woken up (saturates to `i32::MAX`). If `count` is `i32::MAX`, wake up all matching /// waiting threads. If `count` is negative, returns -EINVAL. -pub(crate) fn futex_wake(address: &AtomicU32, count: i32) -> i32 { +/// `address` is used only for its address. +/// It is safe to pass a dangling pointer. +pub(crate) fn futex_wake(address: *const AtomicU32, count: i32) -> i32 { if count < 0 { return -EINVAL; } let mut parking_lot = PARKING_LOT.lock(); - let mut queue = match parking_lot.entry(addr(address)) { + let mut queue = match parking_lot.entry(address.addr()) { Entry::Occupied(entry) => entry, Entry::Vacant(_) => return 0, }; diff --git a/src/syscalls/futex.rs b/src/syscalls/futex.rs index b869c1d1d0..ffe3d5e9f3 100644 --- a/src/syscalls/futex.rs +++ b/src/syscalls/futex.rs @@ -41,6 +41,8 @@ pub unsafe extern "C" fn sys_futex_wait( /// Like `synch::futex_wake`, but does extra sanity checks. /// /// Returns -EINVAL if `address` is null. +/// `address` is used only for its address. +/// It is safe to pass a dangling pointer. #[hermit_macro::system] #[no_mangle] pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { @@ -48,6 +50,5 @@ pub unsafe extern "C" fn sys_futex_wake(address: *mut u32, count: i32) -> i32 { return -EINVAL; } - let address = unsafe { &*(address as *const AtomicU32) }; - synch::futex_wake(address, count) + synch::futex_wake(address as *const AtomicU32, count) }