Re: [PATCH] mm/userfaultfd: only allocate anon_vma in CoW mappings
From: Muchun Song
Date: Thu Oct 15 2026 - 04:39:55 EST
> On Oct 14, 2026, at 19:53, David Hildenbrand (Arm) <david@xxxxxxxxxx> wrote:
>
> find_vma_and_prepare_anon() can end up allocating an anon_vma in VMAs that
> are not CoW mappings, which is wrong.
>
> If we have a MAP_SHARED R/O file mapped, we lack VM_SHARED (but do have
> VM_MAYSHARE) and lack VM_MAYWRITE.
>
> While uffd later rejects such mappings (uffd registration requires
> VM_MAYWRITE, see comment in validate_dst_vma) find_vma_and_prepare_anon()
> still wrongly allocates an anon vma before it validates the vma.
>
> This in turn later confuses copy_page_range()->vma_needs_copy() such
> that we end up calling copy_hugetlb_page_range() with ranges that
> actually do not contain *any* per-pagetable information that would
> require copying, which is the basis for PMD-table sharing in the first
> place.
>
> copy_hugetlb_page_range() should not have to worry about shared
> PMD tables at all: it doesn't make any sense to copy page tables that are
> shared, as they can be fully recreated later. Ending up in the function
> with shareable page tables is the real issue.
>
> If a destination PMD table is shared in copy_hugetlb_page_range(), it
> might get concurrently unshared as we are not holding relevant
> locks, resulting in us using a page table that is no longer mapped and
> possibly freed after calling:
>
> dst_pte = huge_pte_alloc(dst, dst_vma, addr, sz);
>
> To fix it, do not allocate an anon_vma in non-CoW mappings and add a
> safety guard to copy_hugetlb_page_range(), making sure that we never
> end up messing with shared PMD tables in there.
>
> Before commit 867a43a34ff8a ("userfaultfd: use per-vma locks in userfaultfd
> operations") we would always validate the VMA before allocating an
> anon_vma, and consequently never wrongly allocate an anon_vma.
>
> As uffd_lock_vma() is part of the same lookup machinery and
> also contains a misleading VM_SHARED check, change that one as well
> directly for consistency.
>
> A follow-up cleanup will stop taking the hugetlb_vma_lock_read(src_vma)
> lock in copy_hugetlb_page_range() entirely. Further, the usage of
> VM_SHARED in userfaultfd code should be cleaned up later to focus on
> CoW vs. non-CoW mappings.
>
> Reported-by: Kyle Zeng <kylebot@xxxxxxxxxx>
> Fixes: 867a43a34ff8a ("userfaultfd: use per-vma locks in userfaultfd operations")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: David Hildenbrand (Arm) <david@xxxxxxxxxx>
Acked-by: Muchun Song <muchun.song@xxxxxxxxx>
Thanks.