Re: [PATCH] x86/mm/pat: acquire mmap lock on page table free to avoid ptdump UAF
From: Lorenzo Stoakes
Date: Sun Jul 12 2026 - 04:57:15 EST
On Sat, Jul 11, 2026 at 01:05:16PM +0300, Mike Rapoport wrote:
> On Fri, Jul 10, 2026 at 12:56:40PM +0100, Lorenzo Stoakes wrote:
> > x86 implements page attribute modification using its Change Page
> > Attributes (CPA) mechanism.
> >
> > This tracks properties of ranges such as cache mode through x86 page
> > attributes, and as part of that logic manipulates kernel page tables.
> >
> > Since commit 41d88484c71c ("x86/mm/pat: restore large ROX pages after
> > fragmentation") ranges of kernel page table entries can be collapsed into
> > huge page table entries as part of this logic.
> >
> > As part of this collapse, it frees the page tables which the collapsed
> > entries previously pointed to, and it does so without any relevant locks
> > being held to preclude concurrent kernel page table walkers.
> >
> > The only way this code can be reached is if CPA_COLLAPSE is specified, and
> > this is only set in set_memory_rox() via:
> >
> > set_memory_rox()
> > -> change_page_attr_set_clr()
> > -> cpa_flush()
> > -> cpa_collapse_large_pages()
> >
> > Notable users of this are execmem and bpf when manipulating executable
> > mappings.
> >
> > However, this is problematic for ptdump, as it walks ranges it does not own
> > and thus runs the risk of a use-after-free on page tables freed underneath
> > it.
> >
> > 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.
> >
> > It is safe to acquire a sleeping lock as all the callers invoke
> > set_memory_rox() from process context and in any case,
> > change_page_attr_set_clr() calls vm_unmap_alias() which ultimately takes a
> > mutex, disallowing atomic context here.
> >
> > We also include cleanup.h in order to use a scoped_guard() to implement
> > this cleanly.
>
> This is a part of another patch, isn't it?
Yeah, as discussed off-list, I think the easiest way now is for me to resend the
whole thing as a 4 patch series.
I was avoiding this, as it makes the stable stuff tricky and means we end up
with a series with different Fixes tags and some stuff requiring ordering
dependencies and some not, but hopefully Andrew will be forgiving :)
And likely I'll just handle the stable stuff manually, ultimately.
>
> > Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
> > Cc: stable@xxxxxxxxxxxxxxx
> > Signed-off-by: Lorenzo Stoakes <ljs@xxxxxxxxxx>
>
> Reviewed-by: Mike Rapoport (Microsoft) <rppt@xxxxxxxxxx>
Thanks!
>
> > ---
> > arch/x86/mm/pat/set_memory.c | 14 +++++++++++---
> > 1 file changed, 11 insertions(+), 3 deletions(-)
>
> --
> Sincerely yours,
> Mike.
Cheers, Lorenzo