Skip to content

Commit c70dce4

Browse files
Ryan Robertsakpm00
authored andcommitted
fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan
make_uffd_wp_pte() was previously doing: pte = ptep_get(ptep); ptep_modify_prot_start(ptep); pte = pte_mkuffd_wp(pte); ptep_modify_prot_commit(ptep, pte); But if another thread accessed or dirtied the pte between the first 2 calls, this could lead to loss of that information. Since ptep_modify_prot_start() gets and clears atomically, the following is the correct pattern and prevents any possible race. Any access after the first call would see an invalid pte and cause a fault: pte = ptep_modify_prot_start(ptep); pte = pte_mkuffd_wp(pte); ptep_modify_prot_commit(ptep, pte); Link: https://lkml.kernel.org/r/[email protected] Fixes: 52526ca ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs") Signed-off-by: Ryan Roberts <[email protected]> Acked-by: David Hildenbrand <[email protected]> Cc: Muhammad Usama Anjum <[email protected]> Cc: Peter Xu <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent ac0476e commit c70dce4

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

fs/proc/task_mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,7 @@ static void make_uffd_wp_pte(struct vm_area_struct *vma,
18251825
pte_t old_pte;
18261826

18271827
old_pte = ptep_modify_prot_start(vma, addr, pte);
1828-
ptent = pte_mkuffd_wp(ptent);
1828+
ptent = pte_mkuffd_wp(old_pte);
18291829
ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent);
18301830
} else if (is_swap_pte(ptent)) {
18311831
ptent = pte_swp_mkuffd_wp(ptent);

0 commit comments

Comments
 (0)