[PATCH 6.1 232/303] mm: migrate_device: fix pte_pfn/pte_dirty called on non-present PTE
Greg Kroah-Hartman <[email protected]>
| Newsgroups | dev.linux.lists.patches,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
6.1-stable review patch. If anyone has any objections, please let me know. ------------------ From: Kefeng Wang <[email protected]> [ Upstream commit 63867c82d0c0c2d182016a32b1cc0103116b0ea5 ] pte_pfn() and pte_dirty() have undefined behaviour when called on a non-present PTE. In migrate_vma_collect_pmd(), these functions may be invoked on non-present entries (e.g., device-private entries), leading to potential crashes from pte_pfn() or incorrect dirty folio accounting from pte_dirty(). Fix both by guarding with pte_present() checks. Link: https://lore.kernel.org/[email protected] Link: https://lore.kernel.org/[email protected] Fixes: fd35ca3d12cc ("mm/migrate_device.c: copy pte dirty bit to page") Fixes: 6c287605fd56 ("mm: remember exclusively mapped anonymous pages with PG_anon_exclusive") Signed-off-by: Kefeng Wang <[email protected]> Reviewed-by: Balbir Singh <[email protected]> Acked-by: Zi Yan <[email protected]> Cc: Alistair Popple <[email protected]> Cc: Byungchul Park <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Gregory Price <[email protected]> Cc: "Huang, Ying" <[email protected]> Cc: Joshua Hahn <[email protected]> Cc: Matthew Brost <[email protected]> Cc: Rakie Kim <[email protected]> Cc: Ying Huang <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]> --- mm/migrate_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) --- a/mm/migrate_device.c +++ b/mm/migrate_device.c @@ -203,7 +203,8 @@ again: bool anon_exclusive; pte_t swp_pte; - flush_cache_page(vma, addr, pte_pfn(pte)); + if (pte_present(pte)) + flush_cache_page(vma, addr, pte_pfn(pte)); anon_exclusive = folio_test_anon(folio) && PageAnonExclusive(page); if (anon_exclusive) { @@ -223,7 +224,7 @@ again: migrate->cpages++; /* Set the dirty flag on the folio now the pte is gone. */ - if (pte_dirty(pte)) + if (pte_present(pte) && pte_dirty(pte)) folio_mark_dirty(folio); /* Setup special migration page table entry */