- Prevent an inconsistent futex operation leading to stale state
exposure -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmW2LAgACgkQEsHwGGHe VUqowBAAiW9aPQmp401DSXLX+bX0oS5IQVEZnAEE3hQTWxdvDoIdmX+SBReSutXy PDm8mZgVtIiUg3V5bu7/9Dgpu7ovRuChJPjjkYFUDcEmzmsMI11W6u8+8eyt8yRd X9LuGUeXPJSI1kadYudhFUhl6X6KcXj4Y+XUqNcyp8yClSEcLriYeiumNApSEzj6 BneO5VBbXTpJq1b7GOlC4MNhNXhx+WlUdJUb3VPLlxy/akxrNs9x0ASdOuqslCq8 X9SJPnKeRh0mpezmWDgU72eQ/3vpvWQzwyXvp2pQGbjArCx7IwwD765NDu0P6651 C/+4ruXmcd+Jp3wuobdHG8/J2NlZQy8tZQm284YkS5vyBQDi4s17hycXw/aeUFpu /3LR1Hppl//u7hkaHszE8vE5l6in4a2XAbk9EozChVj/aHRJqIaLn8TGQRquK4Tg uRjIC3O2ubJCsIlNIczysjCobSCO+cELwUuFVHh7cdmQAgUwF3efDab0+pJ7MHFb ZEcqQbIt4FGea4BGzvRYCYj6W9bkhzttnH+68ef+mDA3BcdGoYnHcQ143M8duNhe 0inWCibQXMFC9EGPjC8Sz8WvzF/L5KL9bPQmO1sitIzH6kbU3o7PBk2Fe4V6+KP9 THK865SJ/9QirjXrGmp9Sle6dqJRUylmt1ts8reOWACZ98LKeWU= =ibuM -----END PGP SIGNATURE----- Merge tag 'locking_urgent_for_v6.8_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull locking fix from Borislav Petkov: - Prevent an inconsistent futex operation leading to stale state exposure * tag 'locking_urgent_for_v6.8_rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: futex: Prevent the reuse of stale pi_state
This commit is contained in:
commit
648f575d5e
|
@ -627,12 +627,21 @@ retry:
|
|||
}
|
||||
|
||||
/*
|
||||
* PI futexes can not be requeued and must remove themselves from the
|
||||
* hash bucket. The hash bucket lock (i.e. lock_ptr) is held.
|
||||
* PI futexes can not be requeued and must remove themselves from the hash
|
||||
* bucket. The hash bucket lock (i.e. lock_ptr) is held.
|
||||
*/
|
||||
void futex_unqueue_pi(struct futex_q *q)
|
||||
{
|
||||
__futex_unqueue(q);
|
||||
/*
|
||||
* If the lock was not acquired (due to timeout or signal) then the
|
||||
* rt_waiter is removed before futex_q is. If this is observed by
|
||||
* an unlocker after dropping the rtmutex wait lock and before
|
||||
* acquiring the hash bucket lock, then the unlocker dequeues the
|
||||
* futex_q from the hash bucket list to guarantee consistent state
|
||||
* vs. userspace. Therefore the dequeue here must be conditional.
|
||||
*/
|
||||
if (!plist_node_empty(&q->list))
|
||||
__futex_unqueue(q);
|
||||
|
||||
BUG_ON(!q->pi_state);
|
||||
put_pi_state(q->pi_state);
|
||||
|
|
|
@ -1135,6 +1135,7 @@ retry:
|
|||
|
||||
hb = futex_hash(&key);
|
||||
spin_lock(&hb->lock);
|
||||
retry_hb:
|
||||
|
||||
/*
|
||||
* Check waiters first. We do not trust user space values at
|
||||
|
@ -1177,12 +1178,17 @@ retry:
|
|||
/*
|
||||
* Futex vs rt_mutex waiter state -- if there are no rt_mutex
|
||||
* waiters even though futex thinks there are, then the waiter
|
||||
* is leaving and the uncontended path is safe to take.
|
||||
* is leaving. The entry needs to be removed from the list so a
|
||||
* new futex_lock_pi() is not using this stale PI-state while
|
||||
* the futex is available in user space again.
|
||||
* There can be more than one task on its way out so it needs
|
||||
* to retry.
|
||||
*/
|
||||
rt_waiter = rt_mutex_top_waiter(&pi_state->pi_mutex);
|
||||
if (!rt_waiter) {
|
||||
__futex_unqueue(top_waiter);
|
||||
raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
|
||||
goto do_uncontended;
|
||||
goto retry_hb;
|
||||
}
|
||||
|
||||
get_pi_state(pi_state);
|
||||
|
@ -1217,7 +1223,6 @@ retry:
|
|||
return ret;
|
||||
}
|
||||
|
||||
do_uncontended:
|
||||
/*
|
||||
* We have no kernel internal state, i.e. no waiters in the
|
||||
* kernel. Waiters which are about to queue themselves are stuck
|
||||
|
|
Loading…
Reference in New Issue