zephyr: sync: Disallow Mutex reentrancy to prevent unsound mutable aliasing (#181)
Problem
zephyr::sync::Mutexwraps Zephyr’s underlyingk_mutex. In Zephyr,k_mutexis recursive by design, allowing the owning thread to lock it multiple times without blocking. Consequently,Mutex::lock()andMutex::try_lock()allowed reentrant acquisition from the same thread.Because
MutexGuardimplementsDerefMut, allowing reentrancy permitted safe Rust code to obtain multiple concurrent mutable references (&mut T) to the inner data:let mutex = Mutex::new(0); let mut g1 = mutex.lock().unwrap(); let mut g2 = mutex.lock().unwrap(); // Succeeded because k_mutex is recursive! let r1: &mut i32 = &mut *g1; let r2: &mut i32 = &mut *g2; // Undefined Behavior: concurrent mutable references to the same dataThis violates Rust’s fundamental aliasing rules (“aliasing XOR mutability”) and introduces undefined behavior in safe code.
Solution
Track whether the mutex is currently locked by a guard using an
AtomicBool:
- In
lock(), acquire the underlyingsys::Mutex. Iflockedwas already true (indicating recursive acquisition by the current thread), immediately unlock thesys::Mutexto restore its lock count and panic with"cannot recursively lock Mutex".- In
try_lock(), acquire the underlyingsys::Mutex. Iflockedwas already true, immediately unlock and returnErr(TryLockError::WouldBlock).- In
MutexGuard::drop(), clearlockedbefore unlockingsys::Mutex.- In
Condvar::wait(), clearlockedbefore callingsys::Condvar::wait()and re-assertlockedupon re-acquiring the mutex.Prior Issues / PRs
Checked the repository issues and pull requests; there are currently no open or linked pull requests or issues addressing mutex reentrancy soundness.
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号