mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
Merge tag 'locking-urgent-2026-06-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking fix from Ingo Molnar: - Fix the incorrect RCU protection in rt_spin_unlock() (Thomas Gleixner) * tag 'locking-urgent-2026-06-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: locking/rt: Fix the incorrect RCU protection in rt_spin_unlock()
This commit is contained in:
@@ -79,10 +79,27 @@ void __sched rt_spin_unlock(spinlock_t *lock) __releases(RCU)
|
||||
{
|
||||
spin_release(&lock->dep_map, _RET_IP_);
|
||||
migrate_enable();
|
||||
rcu_read_unlock();
|
||||
|
||||
if (unlikely(!rt_mutex_cmpxchg_release(&lock->lock, current, NULL)))
|
||||
rt_mutex_slowunlock(&lock->lock);
|
||||
|
||||
/*
|
||||
* This must be last to prevent the following UAF:
|
||||
*
|
||||
* T1 T2
|
||||
* spin_lock(&p->lock); rcu_read_lock();
|
||||
* invalidate(p); p = rcu_dereference(ptr);
|
||||
* rcu_assign_pointer(ptr, NULL); if (!p) return;
|
||||
* spin_unlock(&p->lock); spin_lock(&p->lock);
|
||||
* kfree_rcu(p); rcu_read_unlock();
|
||||
* ....
|
||||
* spin_unlock(&p->lock)
|
||||
* rcu_read_unlock(); // Ends grace period
|
||||
* rcu_do_batch()
|
||||
* kfree(p);
|
||||
* UAF -> rt_mutex_cmpxchg_release(&p->lock.lock...)
|
||||
*/
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(rt_spin_unlock);
|
||||
|
||||
@@ -262,17 +279,21 @@ void __sched rt_read_unlock(rwlock_t *rwlock) __releases(RCU)
|
||||
{
|
||||
rwlock_release(&rwlock->dep_map, _RET_IP_);
|
||||
migrate_enable();
|
||||
rcu_read_unlock();
|
||||
rwbase_read_unlock(&rwlock->rwbase, TASK_RTLOCK_WAIT);
|
||||
|
||||
/* This must be last. See comment in rt_spin_unlock() */
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(rt_read_unlock);
|
||||
|
||||
void __sched rt_write_unlock(rwlock_t *rwlock) __releases(RCU)
|
||||
{
|
||||
rwlock_release(&rwlock->dep_map, _RET_IP_);
|
||||
rcu_read_unlock();
|
||||
migrate_enable();
|
||||
rwbase_write_unlock(&rwlock->rwbase);
|
||||
|
||||
/* This must be last. See comment in rt_spin_unlock() */
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(rt_write_unlock);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user