VMA Cache Use-After-Free Vulnerability
Since commit 615d6e8756c8 ("mm: per-thread vma caching", first in 3.15), Linux has per-task VMA caches that contain up to four VMA pointers for fast lookup. VMA caches are invalidated by bumping the 32-bit per-mm sequence number mm->vmacache_seqnum; when the sequence number wraps, vmacache_flush_all() scans through all running tasks and wipes the VMA caches of all tasks that share current's mm. In commit 6b4ebc3a9078 ("mm,vmacache: optimize overflow system-wide flushing", first in 3.16), a bogus fastpath was added that skips the invalidation on overflow if current->mm->mm_users==1. This means that the following sequence of events triggers a use-after-free: [A starts as a singlethreaded process] A: create mappings X and Y (in separate memory areas far away from other allocations) A: perform repeated invalidations until current->mm->vmacache_seqnum==0xffffffff and current->vmacache.seqnum==0xfffffffe A: dereference an address in mapping Y that is not paged in (thereby populating A's VMA cache with Y at seqnum 0xffffffff) A: unmap mapping X (thereby bumping current->mm->vmacache_seqnum to 0) A: without any more find_vma() calls (which could happen e.g. via pagefaults), create a thread B B: perform repeated invalidations until current->mm->vmacache_seqnum==0xfffffffe B: unmap mapping Y (thereby bumping current->mm->vmacache_seqnum to 0xffffffff) A: dereference an address in the freed mapping Y (or any address that isn't present in the pagetables and doesn't correspond to a valid VMA cache entry)