Skip to content

Commit 292411f

Browse files
devnexenakpm00
authored andcommitted
mm/userfaultfd: detect VMA type change after copy retry in mfill_copy_folio_retry()
mfill_copy_folio_retry() drops mmap_lock for the copy_from_user() call. During this window, the VMA can be replaced with a different type (e.g. hugetlb), making the caller's ops pointer stale. Subsequent use of the stale ops would dispatch into the wrong per-vma handlers. Capture the VMA's ops via vma_uffd_ops() before dropping the lock and compare against the current vma_uffd_ops() after re-acquiring it. Return -EAGAIN if they differ so the operation can be retried. This avoids comparing against the caller's ops which may have been overridden to anon_uffd_ops for MAP_PRIVATE file-backed mappings. Link: https://lore.kernel.org/20260424183638.196227-1-devnexen@gmail.com Fixes: 6ab7030 ("userfaultfd: mfill_atomic(): remove retry logic") Reported-by: Usama Arif <usama.arif@linux.dev> Closes: https://lore.kernel.org/all/20260410114809.3592720-1-usama.arif@linux.dev/ Signed-off-by: David Carlier <devnexen@gmail.com> Acked-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Cc: Jann Horn <jannh@google.com> Cc: Liam Howlett <liam.howlett@oracle.com> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Peter Xu <peterx@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent ba13b28 commit 292411f

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

mm/userfaultfd.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,8 +443,10 @@ static int mfill_copy_folio_locked(struct folio *folio, unsigned long src_addr)
443443
return ret;
444444
}
445445

446-
static int mfill_copy_folio_retry(struct mfill_state *state, struct folio *folio)
446+
static int mfill_copy_folio_retry(struct mfill_state *state,
447+
struct folio *folio)
447448
{
449+
const struct vm_uffd_ops *orig_ops = vma_uffd_ops(state->vma);
448450
unsigned long src_addr = state->src_addr;
449451
void *kaddr;
450452
int err;
@@ -465,6 +467,14 @@ static int mfill_copy_folio_retry(struct mfill_state *state, struct folio *folio
465467
if (err)
466468
return err;
467469

470+
/*
471+
* The VMA type may have changed while the lock was dropped
472+
* (e.g. replaced with a hugetlb mapping), making the caller's
473+
* ops pointer stale.
474+
*/
475+
if (vma_uffd_ops(state->vma) != orig_ops)
476+
return -EAGAIN;
477+
468478
err = mfill_establish_pmd(state);
469479
if (err)
470480
return err;

0 commit comments

Comments
 (0)