Files
RedBear-OS/local/patches/relibc/absorbed/P5-robust-mutex-enotrec-fix.patch
vasilito b9874d0941 feat: USB storage read/write proof + full Red Bear OS tree sync
Add redbear-usb-storage-check in-guest binary that validates USB mass
storage read and write I/O: discovers /scheme/disk/ devices, writes a
test pattern to sector 2048, reads it back, verifies match, restores
original content. Updates test-usb-storage-qemu.sh with write-proof
verification step.

Includes all accumulated Red Bear OS work: kernel patches, relibc
patches, driver infrastructure, DRM/GPU, KDE recipes, firmware,
validation tooling, build system hardening, and documentation.
2026-05-03 23:03:24 +01:00

65 lines
2.7 KiB
Diff

Fix ENOTRECOVERABLE returned for non-robust mutexes and register main
thread in OS_TID_TO_PTHREAD.
The robust mutex liveness check (mutex_owner_id_is_live) was returning
ENOTRECOVERABLE for non-robust mutexes when the owner appeared dead.
Per POSIX, the behaviour of a non-robust mutex whose owner has died is
undefined; returning an error crashes every Rust std::sync::Mutex user.
For lock_inner, fall through to spin/futex-wait instead. For try_lock,
return EBUSY instead.
Additionally, pthread::init() never registered the main thread in
OS_TID_TO_PTHREAD, so any mutex owned by the main thread would always
appear to have a dead owner, making the liveness check unreliable.
diff --git a/src/pthread/mod.rs b/src/pthread/mod.rs
index 8243a48..c455a67 100644
--- a/src/pthread/mod.rs
+++ b/src/pthread/mod.rs
@@ -43,9 +43,13 @@ pub unsafe fn init() {
thread.stack_size = STACK_SIZE;
}
- unsafe { Tcb::current() }
- .expect_notls("no TCB present for main thread")
- .pthread = thread;
+ let tcb = unsafe { Tcb::current() }
+ .expect_notls("no TCB present for main thread");
+ tcb.pthread = thread;
+
+ OS_TID_TO_PTHREAD
+ .lock()
+ .insert(Sys::current_os_tid(), ForceSendSync(tcb as *const Tcb as *mut Tcb));
}
//static NEXT_INDEX: AtomicU32 = AtomicU32::new(FIRST_THREAD_IDX + 1);
diff --git a/src/sync/pthread_mutex.rs b/src/sync/pthread_mutex.rs
index af0c429..1b2b3ca 100644
--- a/src/sync/pthread_mutex.rs
+++ b/src/sync/pthread_mutex.rs
@@ -136,11 +136,7 @@ impl RlctMutex {
Err(thread) => {
let owner = thread & INDEX_MASK;
- if !crate::pthread::mutex_owner_id_is_live(owner) {
- if !self.robust {
- return Err(Errno(ENOTRECOVERABLE));
- }
-
+ if !crate::pthread::mutex_owner_id_is_live(owner) && self.robust {
let new_value = (thread & WAITING_BIT) | FUTEX_OWNER_DIED | this_thread;
match self.inner.compare_exchange(
thread,
@@ -152,6 +155,11 @@ impl RlctMutex {
Ok(_) => return self.finish_lock_acquire(true),
Err(_) => continue,
}
+ } else if !crate::pthread::mutex_owner_id_is_live(owner) {
+ // Non-robust mutex with apparently-dead owner: per POSIX the
+ // behaviour is undefined. We conservatively keep spinning /
+ // futex-waiting rather than returning ENOTRECOVERABLE, which
+ // would crash any Rust std::sync::Mutex user.
}
if spins_left > 0 {