--- rtmutex.c.orig 2026-07-11 22:50:37.103680678 +0000 +++ rtmutex.c 2026-07-11 22:51:00.603868654 +0000 @@ -610,13 +610,27 @@ { int first = (waiter == rt_mutex_top_waiter(lock)); struct task_struct *owner = rt_mutex_owner(lock); + /* + * CVE-2026-43499 (GhostLock) fix: use the waiter's own task + * instead of current. task_blocks_on_rt_mutex() always sets + * waiter->task before returning (success or -EDEADLK), so this + * is valid for every caller of remove_waiter(). For the ordinary + * self-blocking path (rt_mutex_slowlock, rt_mutex_finish_proxy_lock) + * waiter->task == current, so behaviour there is unchanged. For the + * proxy path (rt_mutex_start_proxy_lock, called from futex_requeue() + * on behalf of another task during FUTEX_CMP_REQUEUE_PI deadlock + * rollback) waiter->task is the *actual* blocked task, which is not + * current -- using current there was the bug: it left the real + * waiter's pi_blocked_on dangling into freed kernel stack memory. + */ + struct task_struct *task = waiter->task; unsigned long flags; int chain_walk = 0; - raw_spin_lock_irqsave(¤t->pi_lock, flags); + raw_spin_lock_irqsave(&task->pi_lock, flags); rt_mutex_dequeue(lock, waiter); - current->pi_blocked_on = NULL; - raw_spin_unlock_irqrestore(¤t->pi_lock, flags); + task->pi_blocked_on = NULL; + raw_spin_unlock_irqrestore(&task->pi_lock, flags); if (!owner) return; @@ -649,7 +663,7 @@ raw_spin_unlock(&lock->wait_lock); - rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, current); + rt_mutex_adjust_prio_chain(owner, 0, lock, NULL, task); raw_spin_lock(&lock->wait_lock); }