Re: [PATCH mm-hotfixes v6 0/5] mm: fix UAF caused by race between ptdump and vmap pgtable freeing
From: Andrew Morton
Date: Thu Jul 23 2026 - 19:27:05 EST
On Thu, 23 Jul 2026 16:16:30 +0100 "Lorenzo Stoakes (ARM)" <ljs@xxxxxxxxxx> wrote:
> Kernel page table walkers fall into two broad categories - those ranges
> where no exclusion is required via walk_kernel_page_table_range_lockless()
> and those where exclusion is required via walk_kernel_page_table_range()
> or walk_page_range_debug().
>
> ...
>
> This series works around this by #ifndef CONFIG_ARM64'ing the mmap read
> lock in vmap logic, then partially reverting commit fa93b45fd397 ("arm64:
> Enable vmalloc-huge with ptdump"), keeping the enablement of huge vmap
> support, and removing the ifdeffery with the partial revert patch.
>
> ...
>
Thanks, I updated the mm-hotfixes-unstable branch to this version.
> ---
> v6:
> * Rebased on latest master of Linus's tree.
> * Updated: 3/5 to drop the init_mm lock over page table allocation in order
> to avoid deadlocks due to init_mm -> ... -> fs_reclaim -> init_mm
> dependency cycles, as reported by Chaitanya with thanks!
> * Small cover letter typo fixes.
Here's how v6 altered mm.git:
arch/x86/mm/pat/set_memory.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/arch/x86/mm/pat/set_memory.c~b
+++ a/arch/x86/mm/pat/set_memory.c
@@ -50,7 +50,8 @@ struct cpa_data {
unsigned int flags;
unsigned int force_split : 1,
force_static_prot : 1,
- force_flush_all : 1;
+ force_flush_all : 1,
+ init_mm_read_locked : 1;
struct page **pages;
};
@@ -1250,7 +1251,11 @@ static int split_large_page(struct cpa_d
if (!debug_pagealloc_enabled())
spin_unlock(&cpa_lock);
+ if (cpa->init_mm_read_locked)
+ mmap_read_unlock(&init_mm);
ptdesc = pagetable_alloc(GFP_KERNEL, 0);
+ if (cpa->init_mm_read_locked)
+ mmap_read_lock(&init_mm);
if (!debug_pagealloc_enabled())
spin_lock(&cpa_lock);
if (!ptdesc)
@@ -2123,8 +2128,10 @@ static int change_page_attr_set_clr(unsi
cpa.force_split = force_split;
/* Avoid race with concurrent CPA collapse. */
+ cpa.init_mm_read_locked = true;
scoped_guard(mmap_read_lock, &init_mm)
ret = __change_page_attr_set_clr(&cpa, 1);
+ cpa.init_mm_read_locked = false;
/*
* Check whether we really changed something:
_