linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/1] userfaultfd: fix a crash when UFFDIO_MOVE handles a THP hole
@ 2025-07-31 15:44 Suren Baghdasaryan
  2025-07-31 17:30 ` Lokesh Gidra
  2025-08-01  7:21 ` David Hildenbrand
  0 siblings, 2 replies; 21+ messages in thread
From: Suren Baghdasaryan @ 2025-07-31 15:44 UTC (permalink / raw)
  To: akpm
  Cc: peterx, david, aarcange, lokeshgidra, surenb, linux-mm,
	linux-kernel, syzbot+b446dbe27035ef6bd6c2, stable

When UFFDIO_MOVE is used with UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES and it
encounters a non-present THP, it fails to properly recognize an unmapped
hole and tries to access a non-existent folio, resulting in
a crash. Add a check to skip non-present THPs.

Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")
Reported-by: syzbot+b446dbe27035ef6bd6c2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/68794b5c.a70a0220.693ce.0050.GAE@google.com/
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Cc: stable@vger.kernel.org
---
Changes since v1 [1]
- Fixed step size calculation, per Lokesh Gidra
- Added missing check for UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES, per Lokesh Gidra

[1] https://lore.kernel.org/all/20250730170733.3829267-1-surenb@google.com/

 mm/userfaultfd.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index cbed91b09640..b5af31c22731 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -1818,28 +1818,41 @@ ssize_t move_pages(struct userfaultfd_ctx *ctx, unsigned long dst_start,
 
 		ptl = pmd_trans_huge_lock(src_pmd, src_vma);
 		if (ptl) {
-			/* Check if we can move the pmd without splitting it. */
-			if (move_splits_huge_pmd(dst_addr, src_addr, src_start + len) ||
-			    !pmd_none(dst_pmdval)) {
-				struct folio *folio = pmd_folio(*src_pmd);
+			if (pmd_present(*src_pmd) || is_pmd_migration_entry(*src_pmd)) {
+				/* Check if we can move the pmd without splitting it. */
+				if (move_splits_huge_pmd(dst_addr, src_addr, src_start + len) ||
+				    !pmd_none(dst_pmdval)) {
+					if (pmd_present(*src_pmd)) {
+						struct folio *folio = pmd_folio(*src_pmd);
+
+						if (!folio || (!is_huge_zero_folio(folio) &&
+							       !PageAnonExclusive(&folio->page))) {
+							spin_unlock(ptl);
+							err = -EBUSY;
+							break;
+						}
+					}
 
-				if (!folio || (!is_huge_zero_folio(folio) &&
-					       !PageAnonExclusive(&folio->page))) {
 					spin_unlock(ptl);
-					err = -EBUSY;
-					break;
+					split_huge_pmd(src_vma, src_pmd, src_addr);
+					/* The folio will be split by move_pages_pte() */
+					continue;
 				}
 
+				err = move_pages_huge_pmd(mm, dst_pmd, src_pmd,
+							  dst_pmdval, dst_vma, src_vma,
+							  dst_addr, src_addr);
+				step_size = HPAGE_PMD_SIZE;
+			} else {
 				spin_unlock(ptl);
-				split_huge_pmd(src_vma, src_pmd, src_addr);
-				/* The folio will be split by move_pages_pte() */
-				continue;
+				if (!(mode & UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES)) {
+					err = -ENOENT;
+					break;
+				}
+				/* nothing to do to move a hole */
+				err = 0;
+				step_size = min(HPAGE_PMD_SIZE, src_start + len - src_addr);
 			}
-
-			err = move_pages_huge_pmd(mm, dst_pmd, src_pmd,
-						  dst_pmdval, dst_vma, src_vma,
-						  dst_addr, src_addr);
-			step_size = HPAGE_PMD_SIZE;
 		} else {
 			if (pmd_none(*src_pmd)) {
 				if (!(mode & UFFDIO_MOVE_MODE_ALLOW_SRC_HOLES)) {

base-commit: 01da54f10fddf3b01c5a3b80f6b16bbad390c302
-- 
2.50.1.552.g942d659e1b-goog



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2025-08-06 15:47 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-31 15:44 [PATCH v2 1/1] userfaultfd: fix a crash when UFFDIO_MOVE handles a THP hole Suren Baghdasaryan
2025-07-31 17:30 ` Lokesh Gidra
2025-08-01  7:21 ` David Hildenbrand
2025-08-01 14:15   ` Peter Xu
2025-08-01 15:28     ` Suren Baghdasaryan
2025-08-01 16:23       ` Peter Xu
2025-08-01 16:41         ` Suren Baghdasaryan
2025-08-01 17:13           ` Peter Xu
2025-08-01 17:45             ` Suren Baghdasaryan
2025-08-01 18:20               ` Peter Xu
2025-08-01 19:30                 ` Suren Baghdasaryan
2025-08-02  0:32                   ` Peter Xu
2025-08-04 14:55                     ` Suren Baghdasaryan
2025-08-05 14:39                       ` Peter Xu
2025-08-05 14:57                         ` Suren Baghdasaryan
2025-08-05 20:39                           ` Suren Baghdasaryan
2025-08-05 23:41                             ` Suren Baghdasaryan
2025-08-06  0:40                               ` Peter Xu
2025-08-06 15:06                                 ` Suren Baghdasaryan
2025-08-06 15:46                                   ` Suren Baghdasaryan
2025-08-01 15:11   ` Suren Baghdasaryan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox