Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: - [Medium] mm/userfaultfd: UFFDIO_MOVE misses crash_memaction registration for swap cache - [Medium] mm: stale crash_memaction marks when moving pages to unmarked VMAs - [Low] mm/rmap: data race on vma->vm_flags in crash_mark_pages() --
commit 78115d9186907359bdb879efc1ef14d161aac39a Author: Jan Sebastian Götte <[email protected]> Subject: mm/rmap: Mark folios mapped into crash_memaction-marked VMAs This patch propagates crash_memaction marks set through madvise() to the crash_memaction registry. It registers folios of a VMA carrying VM_CRASH_MARK as they are mapped, and updates the registry when a folio moves. It also hooks into the free path to deregister pages and avoid tracking stale data. > diff --git a/include/linux/crash_memaction.h b/include/linux/crash_memaction.h > index 5f3e114c60ad7..2de60bc12dd9f 100644 > --- a/include/linux/crash_memaction.h > +++ b/include/linux/crash_memaction.h [ ... ] > @@ -50,6 +51,18 @@ static inline void crash_memaction_unmark_pfns(unsigned > long pfn, > __crash_memaction_unmark_pfns(pfn, nr_pages); > } > > +static inline void crash_mark_pages(struct page *page, int nr_pages, > + struct vm_area_struct *vma) > +{ > + if (!static_branch_unlikely(&crash_memaction_active)) > + return; > + > + if (likely(!(vma->vm_flags & VM_CRASH_MARK))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [Severity: Low] Should this lockless read of vma->vm_flags use READ_ONCE()? The crash_mark_pages() function is called via folio_add_anon_rmap_ptes() during migration (such as in remove_migration_pte()) holding only the anon_vma lock. At the same time, mprotect() can update vma->vm_flags while holding the VMA lock, but not the anon_vma lock. Could this concurrent modification lead to a data race or torn reads during migration? > + return; > + > + __crash_memaction_mark_pfns(page_to_pfn(page), nr_pages); > +} > + > void crash_memaction_mark(void *addr, size_t size, int types); > void crash_memaction_unmark(void *addr, size_t size); > [ ... ] > diff --git a/mm/huge_memory.c b/mm/huge_memory.c > index 3fb9504dff7a9..adbda968d58ef 100644 > --- a/mm/huge_memory.c > +++ b/mm/huge_memory.c > @@ -2966,6 +2966,8 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t > *dst_pmd, pmd_t *src_pmd, pm > > folio_move_anon_rmap(src_folio, dst_vma); > src_folio->index = linear_anon_page_index(dst_vma, dst_addr); > + /* No rmap add, and the two VMAs need not agree on the flag. */ > + crash_mark_pages(&src_folio->page, HPAGE_PMD_NR, dst_vma); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [Severity: Medium] How are stale crash_memaction marks handled when moving to an unmarked VMA? If a process marks a VMA with MADV_CRASH_CACHE, then moves an exclusive anonymous page to an unmarked VMA via mremap() here in move_pages_huge_pmd(), the destination VMA is checked but the source VMA is not unmarked. Because the new VMA lacks the mark, a subsequent madvise(MADV_CRASH_RESET) will short-circuit and fail to unmark the pages. Will these pages remain permanently marked and excluded from kdump dumps until freed, potentially risking data loss? > > _dst_pmd = folio_mk_pmd(src_folio, dst_vma->vm_page_prot); > /* Follow mremap() behavior and treat the entry dirty after the > move */ [ ... ] > diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c > index b242fa8b22c8c..bb0a35d59daa9 100644 > --- a/mm/userfaultfd.c > +++ b/mm/userfaultfd.c > @@ -1326,6 +1326,7 @@ static long move_present_ptes(struct mm_struct *mm, > > folio_move_anon_rmap(src_folio, dst_vma); > src_folio->index = linear_anon_page_index(dst_vma, dst_addr); > + crash_mark_pages(&src_folio->page, 1, dst_vma); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [Severity: Medium] Similar to the mremap() case above, does move_present_ptes() fail to unmark the PFN if the page came from a marked src_vma but is moving to an unmarked dst_vma? [Severity: Medium] Are we missing crash_memaction registration for swap cache folios during UFFDIO_MOVE? While the rmap is updated for present PTEs with a crash_mark_pages() call here, the parallel move_swap_pte() path in mm/userfaultfd.c seems to omit it: if (src_folio) { folio_move_anon_rmap(src_folio, dst_vma); src_folio->index = linear_anon_page_index(dst_vma, dst_addr); } else { If a process marks a VMA with MADV_CRASH_SECRET, and then uses UFFDIO_MOVE to move a swapped-out but swapcache-resident page into this VMA, the page registration is skipped. If the system crashes before the page is faulted in, is there a risk that the kdump kernel will dump the unmarked RAM and leak the secret data? > > orig_dst_pte = folio_mk_pte(src_folio, dst_vma->vm_page_prot); > /* Set soft dirty bit so userspace can notice the pte was moved > */ -- Sashiko AI review · https://sashiko.dev/#/patchset/20260928-crash-memaction-upstream-20260921-v3-0-e511e9ee2...@jaseg.de?part=9

