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 v3 1/4] mm/vmalloc: acquire init_mm lock on huge vmap to avoid ptdump UAF
Date: Tue, 14 Jul 2026 17:40:24 +0000	[thread overview]
Message-ID: <20260714174025.796481F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260714-series-vmap-race-fix-v3-1-b812eccfa0f9@kernel.org>

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

Pre-existing issues:
- [High] The patch attempts to fix a Use-After-Free race between vmap huge page promotion and ptdump by taking a read trylock on `init_mm.mmap_lock` before freeing page tables. However, the fix is incomplete. On x86 and arm64, ptdump can walk kernel page tables via `efi_mm` or `current->mm` (e.g., through `/sys/kernel/debug/page_tables/current_kernel`). In these cases, ptdump acquires the `mmap_write_lock` for the specific `mm` being walked, but does NOT acquire `init_mm.mmap_lock`. As a result, the trylock in `vmap_try_huge_pmd()` will succeed, and vmap will free the shared kernel page tables while ptdump is actively walking them, leaving the UAF unresolved.
--

--- Patch [1]: [PATCH mm-hotfixes v3 1/4] mm/vmalloc: acquire init_mm lock on huge vmap to avoid ptdump UAF ---
commit c32cd4adc90548fc5b0ca8b1bc9ac0e27ae2f214
Author: Lorenzo Stoakes <ljs@kernel.org>

mm/vmalloc: acquire init_mm lock on huge vmap to avoid ptdump UAF

This commit attempts to fix a Use-After-Free race between ptdump and vmap huge
page promotion by acquiring a read trylock on init_mm.mmap_lock before freeing
page tables.

Link: https://lore.kernel.org/linux-mm/20260706203128.162335-1-devnexen@gmail.com/
Closes: https://lore.kernel.org/all/6a287988.39669fcc.33b062.00a0.GAE@google.com/T/

> diff --git a/mm/pagewalk.c b/mm/pagewalk.c
> index 3ae2586ff45b4..bbcfd68d0907d 100644
> --- a/mm/pagewalk.c
> +++ b/mm/pagewalk.c
> @@ -691,6 +693,16 @@ int walk_page_range_debug(struct mm_struct *mm, unsigned long start,
>  		.no_vma		= true
>  	};
>  
> +	/*
> +	 * When walking userland page tables, an mmap write lock must be held to
> +	 * account for munmap() downgrading to an mmap read lock when tearing
> +	 * down page tables.
> +	 *
> +	 * When walking kernel page tables, an mmap write lock must also be held
> +	 * to account for page table freeing on vmap huge page mapping.
> +	 */
> +	mmap_assert_write_locked(mm);
> +

[Severity: High]
This isn't a bug introduced by this patch, but does this assertion fully
protect shared kernel page tables during ptdump walks?

If ptdump walks kernel page tables via efi_mm or current->mm (for example,
through /sys/kernel/debug/page_tables/current_kernel), it locks the specific
mm being walked. This satisfies mmap_assert_write_locked(mm) in
walk_page_range_debug(), but it leaves init_mm unlocked.

>  	/* For convenience, we allow traversal of kernel mappings. */
>  	if (mm == &init_mm)
>  		return walk_kernel_page_table_range(start, end, ops,

[ ... ]

> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index 1afca3568b9b6..1fa9ac6e43d4f 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -158,10 +159,25 @@ static int vmap_try_huge_pmd(pmd_t *pmd, unsigned long addr, unsigned long end,
>  	if (!IS_ALIGNED(phys_addr, PMD_SIZE))
>  		return 0;
>  
> -	if (pmd_present(*pmd) && !pmd_free_pte_page(pmd, addr))
> -		return 0;
> +	if (!pmd_present(*pmd))
> +		return pmd_set_huge(pmd, phys_addr, prot);
>  
> -	return pmd_set_huge(pmd, phys_addr, prot);
> +	/*
> +	 * Kernel page table walkers either walk ranges they own exclusively or
> +	 * hold the mmap write lock on init_mm (ptdump being the motivating
> +	 * case).
> +	 *
> +	 * Therefore, acquire the mmap read lock to prevent use-after-free when
> +	 * freeing page tables.
> +	 */
> +#ifndef CONFIG_ARM64
> +	scoped_cond_guard(mmap_read_lock_try, return 0, &init_mm)
> +#endif
> +	{

[Severity: High]
This is a pre-existing issue, but does locking only init_mm here completely
resolve the use-after-free?

Because ptdump can walk shared kernel page tables (above TASK_SIZE) using
efi_mm or current->mm, it will acquire the mmap_lock for that specific mm,
not init_mm. 

In that scenario, this trylock on init_mm.mmap_lock will succeed. This allows
vmap to free the PTE page while ptdump is actively reading it, leaving the
use-after-free unresolved for these specific debugfs paths.

> +		if (!pmd_free_pte_page(pmd, addr))
> +			return 0;
> +		return pmd_set_huge(pmd, phys_addr, prot);
> +	}
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260714-series-vmap-race-fix-v3-0-b812eccfa0f9@kernel.org?part=1

  reply	other threads:[~2026-07-14 17:40 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-14 17:24 [PATCH mm-hotfixes v3 0/4] mm: fix UAF caused by race between ptdump and vmap pgtable freeing Lorenzo Stoakes
2026-07-14 17:24 ` [PATCH mm-hotfixes v3 1/4] mm/vmalloc: acquire init_mm lock on huge vmap to avoid ptdump UAF Lorenzo Stoakes
2026-07-14 17:40   ` sashiko-bot [this message]
2026-07-15 10:34   ` Kiryl Shutsemau
2026-07-15 14:16     ` Lorenzo Stoakes (ARM)
2026-07-15 19:14       ` Andrew Morton
2026-07-14 17:24 ` [PATCH mm-hotfixes v3 2/4] x86/mm/pat: acquire mmap lock on page table free " Lorenzo Stoakes
2026-07-14 17:29   ` Dave Hansen
2026-07-15  8:49     ` Lorenzo Stoakes (ARM)
2026-07-15 15:24   ` Will Deacon
2026-07-15 15:49     ` Mike Rapoport
2026-07-14 17:24 ` [PATCH mm-hotfixes v3 3/4] mm/ptdump: always stabilise against page table freeing using init_mm Lorenzo Stoakes
2026-07-15 10:36   ` Kiryl Shutsemau
2026-07-14 17:24 ` [PATCH mm-hotfixes v3 4/4] arm64: remove redundant concurrent ptdump UAF mitigation Lorenzo Stoakes
2026-07-14 17:31 ` [PATCH mm-hotfixes v3 0/4] mm: fix UAF caused by race between ptdump and vmap pgtable freeing Dave Hansen
2026-07-15  7:28   ` Lorenzo Stoakes (ARM)
2026-07-14 19:11 ` Andrew Morton
2026-07-15  8:31   ` Lorenzo Stoakes (ARM)

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=20260714174025.796481F000E9@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.