In the Linux kernel, the following vulnerability has been resolved:
mm: fix a UAF when vma->mm is freed after vma->vm_refcnt got dropped
By inducing delays in the right places, Jann Horn created a reproducer for a hard to hit UAF issue that became possible after VMAs were allowed to be recycled by adding SLAB_TYPESAFE_BY_RCU to their cache.
Race description is borrowed from Jann's discovery report: lock_vma_under_rcu() looks up a VMA locklessly with mas_walk() under rcu_read_lock(). At that point, the VMA may be concurrently freed, and it can be recycled by another process. vma_start_read() then increments the vma->vm_refcnt (if it is in an acceptable range), and if this succeeds, vma_start_read() can return a recycled VMA.
In this scenario where the VMA has been recycled, lock_vma_under_rcu() will then detect the mismatching ->vm_mm pointer and drop the VMA through vma_end_read(), which calls vma_refcount_put(). vma_refcount_put() drops the refcount and then calls rcuwait_wake_up() using a copy of vma->vm_mm. This is wrong: It implicitly assumes that the caller is keeping the VMA's mm alive, but in this scenario the caller has no relation to the VMA's mm, so the rcuwait_wake_up() can cause UAF.
The diagram depicting the race: T1 T2 T3 == == == lock_vma_under_rcu mas_walk <VMA gets removed from mm> mmap <the same VMA is reallocated> vma_start_read __refcount_inc_not_zero_limited_acquire munmap __vma_enter_locked refcount_add_not_zero vma_end_read vma_refcount_put __refcount_dec_and_test rcuwait_wait_event <finish operation> rcuwait_wake_up [UAF]
Note that rcuwait_wait_event() in T3 does not block because refcount was already dropped by T1. At this point T3 can exit and free the mm causing UAF in T1.
To avoid this we move vma->vm_mm verification into vma_start_read() and grab vma->vm_mm to stabilize it before vma_refcount_put() operation.
[[email protected]: v3]
| Product | Vendor Advisory | Solution File | Added | Published |
|---|---|---|---|---|
| Suse | — | Upgrade kernel-64kbUpgrade kernel-default-livepatchUpgrade dtb-amlogicUpgrade dtb-socionextUpgrade kernel-macrosUpgrade kernel-zfcpdumpUpgrade gfs2-kmp-rtUpgrade kernel-rtUpgrade kselftests-kmp-defaultUpgrade kernel-rt-extraUpgrade dtb-amdUpgrade kernel-docsUpgrade kernel-rt-optionalUpgrade kernel-defaultUpgrade kernel-kvmsmallUpgrade kernel-rt-livepatch-develUpgrade kernel-default-extraUpgrade dtb-apmUpgrade kernel-kvmsmall-develUpgrade kernel-kvmsmall-vdsoUpgrade kernel-obs-buildUpgrade dtb-marvellUpgrade kernel-rt-vdsoUpgrade dlm-kmp-defaultUpgrade kernel-obs-qaUpgrade dtb-broadcomUpgrade ocfs2-kmp-rtUpgrade cluster-md-kmp-defaultUpgrade kernel-docs-htmlUpgrade kernel-default-develUpgrade kernel-source-vanillaUpgrade ocfs2-kmp-64kbUpgrade dtb-amazonUpgrade dtb-appleUpgrade dtb-freescaleUpgrade kselftests-kmp-rtUpgrade dtb-nvidiaUpgrade dtb-lgUpgrade gfs2-kmp-defaultUpgrade cluster-md-kmp-rtUpgrade dtb-armUpgrade dtb-caviumUpgrade kernel-rt-develUpgrade gfs2-kmp-64kbUpgrade dtb-rockchipUpgrade dtb-qcomUpgrade cluster-md-kmp-64kbUpgrade kernel-develUpgrade dtb-exynosUpgrade dtb-allwinnerUpgrade kernel-64kb-optionalUpgrade dtb-alteraUpgrade dtb-renesasUpgrade kernel-64kb-develUpgrade kselftests-kmp-64kbUpgrade dtb-sprdUpgrade kernel-sourceUpgrade kernel-default-livepatch-develUpgrade kernel-64kb-extraUpgrade kernel-rt-livepatchUpgrade dtb-hisiliconUpgrade dtb-xilinxUpgrade dlm-kmp-rtUpgrade kernel-default-optionalUpgrade dlm-kmp-64kbUpgrade dtb-mediatekUpgrade ocfs2-kmp-defaultUpgrade kernel-symsUpgrade kernel-default-vdso | Dec 5, 2025 | Nov 6, 2025 |
With curated Threat Intelligence, you can see which vulnerabilities truly put you at risk, prioritize what matters most, and act before attackers do.
Explore Intelligence Hub