[PATCH 23/46] mm/userfaultfd: write-lock the VMA before waking waiters when unregistering

Lorenzo Stoakes (ARM) ljs at kernel.org
Tue Oct 27 01:43:14 PDT 2026


On Tue, Oct 27, 2026 at 12:17:43AM +0100, David Hildenbrand (Arm) wrote:
> userfaultfd_unregister() wakes pending missing faults before clearing the
> VMA's userfaultfd registration. With per-VMA fault locking, holding
> mmap_lock for write does not prevent another fault from queuing after
> the wakeup but before userfaultfd_clear_vma() write-locks the VMA. That
> waiter can then remain asleep indefinitely.

Oof.

I guess userfaultfd_clear_vma() only implicitly takes the VMA write lock via
vma_modify_flags_uffd().

>
> Call vma_start_write() before waking waiters. Existing fault handlers
> queue themselves before dropping the VMA read lock, and new readers are
> excluded until mmap_write_unlock().

Clearly an oversight from the VMA locks work. I guess was always a Herculean
task to catch every single point at which there is an implicit assumption that
mmap write lock ~ readers (esp. faults) excluded.

>
> Fixes: 29a22b9e08d7 ("mm: handle userfaults under VMA lock")
> Cc: stable at vger.kernel.org
> Reported-by: Josef Bacik <josef at toxicpanda.com>
> Signed-off-by: David Hildenbrand (Arm) <david at kernel.org>

Reviewed-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>

> ---
>  mm/userfaultfd.c | 3 +++
>  1 file changed, 3 insertions(+)
>
> diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
> index 669f71d485d02..7e30b5ff17be1 100644
> --- a/mm/userfaultfd.c
> +++ b/mm/userfaultfd.c
> @@ -3991,6 +3991,9 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
>  			start = vma->vm_start;
>  		vma_end = min(end, vma->vm_end);
>
> +		/* Prevent new userfaults from being queued after the wakeup. */
> +		vma_start_write(vma);
> +
>  		if (userfaultfd_missing(vma)) {
>  			/*
>  			 * Wake any concurrent pending userfault while
>
> --
> 2.43.0
>

--
Cheers, Lorenzo



More information about the kexec mailing list