Re: [PATCH] x86/mm/pat: acquire mmap lock on page table free to avoid ptdump UAF
From: Dave Hansen
Date: Fri Jul 10 2026 - 12:30:40 EST
On 7/10/26 04:56, Lorenzo Stoakes wrote:
> This patch resolves the issue by acquiring the mmap read lock on init_mm to
> provide mutual exclusion against ptdump, which acquires the init_mm write
> lock.
Hey Lorenzo,
Thanks for looking at this!
This isn't wrong per-se. ptdump does _sometimes_ acquire the init_mm
write lock.
But the fun comes when ptdump_curknl_show() passes current->mm in to the
ptdump code. In that case, there's no init_mm locking. I think the
'efi_mm' code has the same issue since it shares some of the kernel page
tables.
Is that your read on it too?
In the end, I think the issue is that there's not even *a* correct mmap
lock to take. The userspace half of the address space needs the
current->mm mmap lock and the kernel half needs the init_mm mmap lock.
The naming here doesn't help because the "current_kernel" file doesn't
dump the current kernel page tables, it dumps the whole kernel *copy*
(the only copy with PTI off) which includes userspace.
(Note: maybe we should hide "current_user" when PTI is off at runtime)
So what do we do?
1. We could just bite the bullet and have separate ptdump files for the
top and bottom of the address space:
current_kernel_top
current_kernel_bottom
current_user_top
current_user_bottom
etc..
Then the lock you take is dictated by the file.
2. We could always take both init_mm and current->mm locks. That seems
icky.
3. We could have ptdump_walk_pgd() take a different lock for each
'range'. Logically:
if (range->start < PAGE_OFFSET)
mmap_write_lock(mm);
else
mmap_write_lock(&init_mm);
That's icky too and it means a range can't cross PAGE_OFFSET, but
that doesn't seem too bad (it could also WARN() if it sees bad
ranges).
4. We do something fancier with the free like RCU (I think this may have
been discussed already).
I'm kinda leaning toward #3.