Skip to content

Commit 927e926

Browse files
surenbaghdasaryanakpm00
authored andcommitted
userfaultfd: fix PTE unmapping stack-allocated PTE copies
Current implementation of move_pages_pte() copies source and destination PTEs in order to detect concurrent changes to PTEs involved in the move. However these copies are also used to unmap the PTEs, which will fail if CONFIG_HIGHPTE is enabled because the copies are allocated on the stack. Fix this by using the actual PTEs which were kmap()ed. Link: https://lkml.kernel.org/r/20250226185510.2732648-3-surenb@google.com Fixes: adef440 ("userfaultfd: UFFDIO_MOVE uABI") Signed-off-by: Suren Baghdasaryan <surenb@google.com> Reported-by: Peter Xu <peterx@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Barry Song <21cnbao@gmail.com> Cc: Barry Song <v-songbaohua@oppo.com> Cc: David Hildenbrand <david@redhat.com> Cc: Hugh Dickins <hughd@google.com> Cc: Jann Horn <jannh@google.com> Cc: Kalesh Singh <kaleshsingh@google.com> Cc: Liam R. Howlett <Liam.Howlett@Oracle.com> Cc: Lokesh Gidra <lokeshgidra@google.com> Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> Cc: Matthew Wilcow (Oracle) <willy@infradead.org> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 37b338e commit 927e926

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

mm/userfaultfd.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,8 +1290,8 @@ static int move_pages_pte(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd,
12901290
spin_unlock(src_ptl);
12911291

12921292
if (!locked) {
1293-
pte_unmap(&orig_src_pte);
1294-
pte_unmap(&orig_dst_pte);
1293+
pte_unmap(src_pte);
1294+
pte_unmap(dst_pte);
12951295
src_pte = dst_pte = NULL;
12961296
/* now we can block and wait */
12971297
folio_lock(src_folio);
@@ -1307,8 +1307,8 @@ static int move_pages_pte(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd,
13071307
/* at this point we have src_folio locked */
13081308
if (folio_test_large(src_folio)) {
13091309
/* split_folio() can block */
1310-
pte_unmap(&orig_src_pte);
1311-
pte_unmap(&orig_dst_pte);
1310+
pte_unmap(src_pte);
1311+
pte_unmap(dst_pte);
13121312
src_pte = dst_pte = NULL;
13131313
err = split_folio(src_folio);
13141314
if (err)
@@ -1333,8 +1333,8 @@ static int move_pages_pte(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd,
13331333
goto out;
13341334
}
13351335
if (!anon_vma_trylock_write(src_anon_vma)) {
1336-
pte_unmap(&orig_src_pte);
1337-
pte_unmap(&orig_dst_pte);
1336+
pte_unmap(src_pte);
1337+
pte_unmap(dst_pte);
13381338
src_pte = dst_pte = NULL;
13391339
/* now we can block and wait */
13401340
anon_vma_lock_write(src_anon_vma);
@@ -1352,8 +1352,8 @@ static int move_pages_pte(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd,
13521352
entry = pte_to_swp_entry(orig_src_pte);
13531353
if (non_swap_entry(entry)) {
13541354
if (is_migration_entry(entry)) {
1355-
pte_unmap(&orig_src_pte);
1356-
pte_unmap(&orig_dst_pte);
1355+
pte_unmap(src_pte);
1356+
pte_unmap(dst_pte);
13571357
src_pte = dst_pte = NULL;
13581358
migration_entry_wait(mm, src_pmd, src_addr);
13591359
err = -EAGAIN;
@@ -1396,8 +1396,8 @@ static int move_pages_pte(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd,
13961396
src_folio = folio;
13971397
src_folio_pte = orig_src_pte;
13981398
if (!folio_trylock(src_folio)) {
1399-
pte_unmap(&orig_src_pte);
1400-
pte_unmap(&orig_dst_pte);
1399+
pte_unmap(src_pte);
1400+
pte_unmap(dst_pte);
14011401
src_pte = dst_pte = NULL;
14021402
put_swap_device(si);
14031403
si = NULL;

0 commit comments

Comments
 (0)