diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c index 9ffc80d0a51b..dbf16c9bcf6f 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -467,6 +467,16 @@ static int mfill_copy_folio_retry(struct mfill_state *state, struct folio *folio if (err) return err; + /* + * VMA may have been split while the lock was dropped for + * copy_from_user(). mfill_get_vma() only validates dst_start + * but not dst_addr (current page). Re-validate dst_addr against + * the reacquired VMA bounds before installing the PTE. + */ + if (state->dst_addr < state->vma->vm_start || + state->dst_addr >= state->vma->vm_end) + return -EFAULT; + err = mfill_get_pmd(state); if (err) return err;