All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Lorenzo Stoakes" <ljs@kernel.org>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH mm-hotfixes v2 2/4] x86/mm/pat: acquire mmap lock on page table free to avoid ptdump UAF
Date: Sun, 12 Jul 2026 11:01:52 +0000	[thread overview]
Message-ID: <20260712110153.3965C1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260712-series-vmap-race-fix-v2-2-ad134cc3a12a@kernel.org>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Lockless walkers of `init_mm` (such as `lookup_address()` and `vmalloc_to_page()`) are entirely unprotected against CPA large page collapse, resulting in use-after-free and severe executable memory corruption.
- [Critical] Kernel page tables are freed locklessly and before being unlinked in the error path of `populate_pgd()`, leading to concurrent ptdump Use-After-Free and hardware page table walker race conditions.
- [High] Acquiring `mmap_read_lock(&init_mm)` does not fully protect against `ptdump` use-after-free, as `ptdump` can walk kernel page tables while holding the `mmap_write_lock` of other `mm_struct`s.
--

--- Patch [2]: [PATCH mm-hotfixes v2 2/4] x86/mm/pat: acquire mmap lock on page table free to avoid ptdump UAF ---
commit e694327eb6fa8a3cd99ff84b5655377d8ebf1050
Author: Lorenzo Stoakes <ljs@kernel.org>
x86/mm/pat: acquire mmap lock on page table free to avoid ptdump UAF

This commit attempts to fix a use-after-free regression when ptdump walks
page tables that are concurrently being freed during a large page
collapse. It does so by acquiring the mmap_read_lock on init_mm around
the page table freeing loop in cpa_collapse_large_pages().

> diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> --- a/arch/x86/mm/pat/set_memory.c
> +++ b/arch/x86/mm/pat/set_memory.c
> @@ -436,9 +437,16 @@ static void cpa_collapse_large_pages(struct cpa_data *cpa)
>  
>  	flush_tlb_all();
>  
> -	list_for_each_entry_safe(ptdesc, tmp, &pgtables, pt_list) {
> -		list_del(&ptdesc->pt_list);
> -		pagetable_free(ptdesc);
> +	/*
> +	 * ptdump might read these page tables, so avoid a use-after-free by
> +	 * acquiring the mmap read lock on init_mm (ptdump acquires the mmap
> +	 * write lock).
> +	 */
> +	scoped_guard(mmap_read_lock, &init_mm) {

[Severity: High]
This is a pre-existing issue, but does acquiring the lock on init_mm fully
protect against ptdump?

Looking at arch/x86/mm/debug_pagetables.c:ptdump_curknl_show(), the walk
is initiated using current->mm:

ptdump_walk_pgd_level_debugfs(m, current->mm, false);

Since this causes ptdump to acquire current->mm->mmap_lock instead of
init_mm's lock, could ptdump still walk these kernel page tables
concurrently with the collapse?

[Severity: Critical]
This is a pre-existing issue, but does taking mmap_read_lock protect
against lockless walkers?

Functions like lookup_address_in_pgd_attr() perform a lockless traversal:

if (pmd_leaf(*pmd) || !pmd_present(*pmd))
    return (pte_t *)pmd;
...
return pte_offset_kernel(pmd, address);

If a lockless walker checks pmd_leaf() just before the large page collapse
overwrites the PMD, could it evaluate pte_offset_kernel() on a huge page
payload instead of a page table array?

> +		list_for_each_entry_safe(ptdesc, tmp, &pgtables, pt_list) {
> +			list_del(&ptdesc->pt_list);
> +			pagetable_free(ptdesc);
> +		}
> +	}
>  }

[ ... ]

[Severity: Critical]
This is a pre-existing issue, but does unmap_pte_range() correctly
sequence freeing and unlinking page tables?

In the error rollback path of populate_pgd(), unmap_pte_range() clears
the PTEs and then calls try_to_free_pte_page():

arch/x86/mm/pat/set_memory.c:unmap_pte_range() {
    ...
    if (try_to_free_pte_page((pte_t *)pmd_page_vaddr(*pmd))) {
        pmd_clear(pmd);
        return true;
    }
    ...
}

Since try_to_free_pte_page() invokes pte_free_kernel() locklessly, the
memory is returned to the allocator before pmd_clear() unlinks the PMD.

Could a concurrent software or hardware page table walker traverse the
freed page before the PMD is cleared?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260712-series-vmap-race-fix-v2-0-ad134cc3a12a@kernel.org?part=2

  reply	other threads:[~2026-07-12 11:01 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-12 10:42 [PATCH mm-hotfixes v2 0/4] mm: fix UAF caused by race between ptdump and vmap pgtable freeing Lorenzo Stoakes
2026-07-12 10:42 ` [PATCH mm-hotfixes v2 1/4] mm/vmalloc: acquire init_mm lock on huge vmap to avoid ptdump UAF Lorenzo Stoakes
2026-07-12 10:55   ` sashiko-bot
2026-07-12 13:17   ` Dev Jain
2026-07-13 16:42   ` Kiryl Shutsemau
2026-07-14  9:46     ` Lorenzo Stoakes
2026-07-12 10:42 ` [PATCH mm-hotfixes v2 2/4] x86/mm/pat: acquire mmap lock on page table free " Lorenzo Stoakes
2026-07-12 11:01   ` sashiko-bot [this message]
2026-07-12 16:53   ` Borislav Petkov
2026-07-14  9:47     ` Lorenzo Stoakes
2026-07-12 10:42 ` [PATCH mm-hotfixes v2 3/4] mm/ptdump: always stabilise against page table freeing using init_mm Lorenzo Stoakes
2026-07-13 17:19   ` Kiryl Shutsemau
2026-07-14  9:49     ` Lorenzo Stoakes
2026-07-12 10:42 ` [PATCH mm-hotfixes v2 4/4] arm64: remove redundant concurrent ptdump UAF mitigation Lorenzo Stoakes
2026-07-13 11:40   ` Will Deacon
2026-07-13 17:21   ` Kiryl Shutsemau
2026-07-13 13:32 ` [PATCH mm-hotfixes v2 0/4] mm: fix UAF caused by race between ptdump and vmap pgtable freeing Kiryl Shutsemau
2026-07-13 15:54   ` Lorenzo Stoakes (ARM)
2026-07-13 16:32     ` Kiryl Shutsemau
2026-07-14 16:20       ` Lorenzo Stoakes (ARM)
2026-07-14 17:05         ` Kiryl Shutsemau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260712110153.3965C1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=ljs@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.