目录
David Brown

zephyr: sync: Disallow Mutex reentrancy to prevent unsound mutable aliasing (#181)

Problem

zephyr::sync::Mutex wraps Zephyr’s underlying k_mutex. In Zephyr, k_mutex is recursive by design, allowing the owning thread to lock it multiple times without blocking. Consequently, Mutex::lock() and Mutex::try_lock() allowed reentrant acquisition from the same thread.

Because MutexGuard implements DerefMut, 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 data

This 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:

  1. In lock(), acquire the underlying sys::Mutex. If locked was already true (indicating recursive acquisition by the current thread), immediately unlock the sys::Mutex to restore its lock count and panic with "cannot recursively lock Mutex".
  2. In try_lock(), acquire the underlying sys::Mutex. If locked was already true, immediately unlock and return Err(TryLockError::WouldBlock).
  3. In MutexGuard::drop(), clear locked before unlocking sys::Mutex.
  4. In Condvar::wait(), clear locked before calling sys::Condvar::wait() and re-assert locked upon 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.

13天前373次提交
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9 京公网安备 11010802047560号