• Thomas Gleixner's avatar
    locking/rtmutex: Dont dereference waiter lockless · c3123c43
    Thomas Gleixner authored
    The new rt_mutex_spin_on_onwer() loop checks whether the spinning waiter is
    still the top waiter on the lock by utilizing rt_mutex_top_waiter(), which
    is broken because that function contains a sanity check which dereferences
    the top waiter pointer to check whether the waiter belongs to the
    lock. That's wrong in the lockless spinwait case:
    
     CPU 0							CPU 1
     rt_mutex_lock(lock)					rt_mutex_lock(lock);
       queue(waiter0)
       waiter0 == rt_mutex_top_waiter(lock)
       rt_mutex_spin_on_onwer(lock, waiter0) {		queue(waiter1)
       					 		waiter1 == rt_mutex_top_waiter(lock)
       							...
         top_waiter = rt_mutex_top_waiter(lock)
           leftmost = rb_first_cached(&lock->waiters);
    							-> signal
    							dequeue(waiter1)
    							destroy(waiter1)
           w = rb_entry(leftmost, ....)
           BUG_ON(w->lock != lock)	 <- UAF
    
    The BUG_ON() is correct for the case where the caller holds lock->wait_lock
    which guarantees that the leftmost waiter entry cannot vanish. For the
    ...
    c3123c43
rtmutex_common.h 6.19 KB