Re: rt_spin_unlock order of operations [was: Re: [syzbot] [fs?] KASAN: slab-use-after-free Read in shrink_dcache_tree]
From: Sebastian Andrzej Siewior
Date: Fri Jun 19 2026 - 04:39:34 EST
On 2026-06-19 00:24:58 [+0200], Thomas Gleixner wrote:
> Right. That's clearly a bug in rt_spin_unlock(). I think I wrote it that
> way for symmetry vs. lock(), which is obviously wrong.
and yet we had it since day one like that.
> Fix below.
>
> Thanks,
>
> tglx
> ---
> Subject: locking/rt: Fix the incorrect RCU protection in rt_spin_unlock()
> From: Thomas Gleixner <tglx@xxxxxxxxxx>
> Date: Thu, 18 Jun 2026 23:32:43 +0200
>
> rt_spin_unlock() releases the RCU protection before unlocking the
> lock. That opens the door for the following UAF scenario:
…
would you mind folding the following? I don't see why the rwlocks should
be treated any different.
diff --git a/kernel/locking/spinlock_rt.c b/kernel/locking/spinlock_rt.c
index db1e11b45de67..4fb77daafd758 100644
--- a/kernel/locking/spinlock_rt.c
+++ b/kernel/locking/spinlock_rt.c
@@ -262,17 +262,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 to prevent, see 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 to prevent, see rt_spin_unlock() */
+ rcu_read_unlock();
}
EXPORT_SYMBOL(rt_write_unlock);