From: David Carlier <devnexen@gmail.com>
To: Andrew Morton <akpm@linux-foundation.org>, Peter Xu <peterx@redhat.com>
Cc: Mike Rapoport <rppt@kernel.org>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
David Carlier <devnexen@gmail.com>
Subject: [PATCH 1/2] mm/userfaultfd: fix stale ops and VMA type mismatch after copy retry
Date: Sat, 28 Mar 2026 17:01:00 +0000 [thread overview]
Message-ID: <20260328170101.184163-1-devnexen@gmail.com> (raw)
In mfill_atomic_pte_copy(), ops is derived from the VMA once and passed
to __mfill_atomic_pte(). When the initial copy_from_user() fails under
pagefault_disable(), mfill_copy_folio_retry() drops all locks, performs
the copy with page faults enabled, then re-acquires locks via
mfill_get_vma(). During this window, the VMA can be replaced entirely
(e.g. munmap + mmap + UFFDIO_REGISTER by another thread), but ops is
never re-validated.
If a shared shmem VMA is replaced by an anonymous VMA, the stale
shmem_uffd_ops->filemap_add calls shmem_mfill_filemap_add() with an
anonymous VMA, causing a NULL pointer dereference at file_inode(vma->
vm_file) since vm_file is NULL for anonymous mappings.
The mmap_changing guard does not fully prevent this because
userfaultfd_unmap_prep() only increments mmap_changing when
UFFD_FEATURE_EVENT_UNMAP is enabled, which is optional. Without it,
munmap proceeds without any signal to the retry path.
The copy_from_user() in the retry runs with page faults enabled and can
block on slow backing stores (FUSE, NFS), significantly widening the
race window.
Fix this by:
- Validating that the VMA's userfaultfd context matches state->ctx in
mfill_get_vma() to detect cross-context VMA replacement.
- Re-checking that vma_uffd_ops() still matches the frozen ops after
the retry, and that the VMA is still VM_SHARED when ops expects it
to be, returning -EAGAIN otherwise.
Signed-off-by: David Carlier <devnexen@gmail.com>
---
mm/userfaultfd.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index 481ec7eb4442..2a6e034b15aa 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -225,8 +225,9 @@ static int mfill_get_vma(struct mfill_state *state)
*/
down_read(&ctx->map_changing_lock);
state->vma = dst_vma;
+
err = -EAGAIN;
- if (atomic_read(&ctx->mmap_changing))
+ if (dst_vma->vm_userfaultfd_ctx.ctx != ctx || atomic_read(&ctx->mmap_changing))
goto out_unlock;
err = -EINVAL;
@@ -498,6 +499,12 @@ static int __mfill_atomic_pte(struct mfill_state *state,
ret = mfill_copy_folio_retry(state, folio);
if (ret)
goto err_folio_put;
+ if (vma_uffd_ops(state->vma) != ops ||
+ (ops != &anon_uffd_ops &&
+ !(state->vma->vm_flags & VM_SHARED))) {
+ ret = -EAGAIN;
+ goto err_folio_put;
+ }
}
} else if (uffd_flags_mode_is(flags, MFILL_ATOMIC_ZEROPAGE)) {
clear_user_highpage(&folio->page, state->dst_addr);
--
2.53.0
next reply other threads:[~2026-03-28 17:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-28 17:01 David Carlier [this message]
2026-03-28 17:01 ` [PATCH 2/2] mm/userfaultfd: fix wrong likely() hint on mmap_changing check in move_pages() David Carlier
2026-03-30 19:39 ` Peter Xu
2026-03-31 11:42 ` Mike Rapoport
2026-03-30 19:38 ` [PATCH 1/2] mm/userfaultfd: fix stale ops and VMA type mismatch after copy retry Peter Xu
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=20260328170101.184163-1-devnexen@gmail.com \
--to=devnexen@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=peterx@redhat.com \
--cc=rppt@kernel.org \
/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.