[PW_SID:1122667] [v8] mm: pgtable: free kernel page tables via RCU to fix ptdump UAF#2231
Closed
linux-riscv-bot wants to merge 2 commits into
Closed
[PW_SID:1122667] [v8] mm: pgtable: free kernel page tables via RCU to fix ptdump UAF#2231linux-riscv-bot wants to merge 2 commits into
linux-riscv-bot wants to merge 2 commits into
Conversation
ptdump_walk_pgd() walks the kernel page tables under get_online_mems(). That does not stop vmalloc from freeing a kernel PTE page underneath the walk. When vmap_try_huge_pmd() promotes a range to a huge PMD it collapses the existing PTE table and frees it via pmd_free_pte_page(). On x86, riscv and powerpc this runs without the init_mm mmap lock; only arm64 takes it, and not on the block-split path. So ptdump can dereference a just-freed PTE page, which is the use after free syzbot hit in ptdump_pte_entry(). The race is not new. ptdump walks the whole kernel address space, including ranges other code is actively mapping, so it reads page tables it does not own. Commit 5ba2f0a ("mm: introduce deferred freeing for kernel page tables") only widened the window; the Fixes tag points there for that reason. Every other walker works on a range it owns and is the only one mutating it: set_memory() on arm64/riscv/loongarch, the arm64 block-split path, the openrisc DMA path and the hugetlb_vmemmap remap. Nothing frees those ranges concurrently, so they cannot race and do not need RCU. ptdump is the only walker that traverses ranges it does not own. Defer the free by an RCU grace period. pagetable_free_kernel() now frees via call_rcu() in both the async and non-async configs. The async path still flushes the TLB first, then queues the per-page RCU free. The page stays valid until any walk that may have observed it drops its RCU read lock. x86, arm64 and riscv reach pagetable_free_kernel() for the collapsed PTE page (the ptdesc carries PT_kernel), so the deferral covers them. powerpc uses its own fragment allocator: pte_free_kernel() there frees the page synchronously via pte_fragment_free() and the ptdesc is not flagged kernel, so defer the kernel case in pte_fragment_free() as well. arm64 also takes init_mm.mmap_lock around the free under a static key; that is now redundant with the RCU deferral but left in place. On the read side walk_page_range_debug() walks the init_mm range in bounded chunks, taking rcu_read_lock() around each chunk and calling cond_resched() between them. It uses the lockless walker as the mmap lock is no longer held, and pgd_addr_end() to bound each chunk without overflowing at the top of the address space. A walker either sees the cleared PMD and skips, or keeps the page alive until it drops the lock. The owned-range walkers are unchanged. Stop taking mmap_write_lock() in ptdump_walk_pgd() for init_mm. It never guarded against this free -- most architectures free the collapsed PTE table without it -- and RCU now provides the synchronisation. efi_mm and current->mm page tables are not RCU-freed, so they keep the mmap write lock. ptdump callbacks run under RCU within a chunk, so they must not sleep. The arch note_page() and effective_prot() callbacks only format into the preallocated seq_file buffer; the only GFP_KERNEL marker setup runs before the walk, and cond_resched() happens between chunks, outside the read lock. Fixes: 5ba2f0a ("mm: introduce deferred freeing for kernel page tables") Reported-by: syzbot+fd95a72470f5a44e464c@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/6a287988.39669fcc.33b062.00a0.GAE@google.com/T/ Assisted-by: Claude:claude-opus-4-8 Signed-off-by: David Carlier <devnexen@gmail.com> Signed-off-by: Linux RISC-V bot <linux.riscv.bot@gmail.com>
linux-riscv-bot
force-pushed
the
workflow__riscv__fixes
branch
7 times, most recently
from
July 13, 2026 20:05
869345e to
f54dc6c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR for series 1122667 applied to workflow__riscv__fixes
Name: [v8] mm: pgtable: free kernel page tables via RCU to fix ptdump UAF
URL: https://patchwork.kernel.org/project/linux-riscv/list/?series=1122667
Version: 8