[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240429114017.182570-1-ryan.roberts@arm.com>
Date: Mon, 29 Apr 2024 12:40:17 +0100
From: Ryan Roberts <ryan.roberts@....com>
To: Andrew Morton <akpm@...ux-foundation.org>,
David Hildenbrand <david@...hat.com>,
Muhammad Usama Anjum <usama.anjum@...labora.com>,
Peter Xu <peterx@...hat.com>
Cc: Ryan Roberts <ryan.roberts@....com>,
linux-kernel@...r.kernel.org,
linux-fsdevel@...r.kernel.org
Subject: [PATCH v1] 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);
Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs")
Signed-off-by: Ryan Roberts <ryan.roberts@....com>
---
fs/proc/task_mmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 23fbab954c20..af4bc1da0c01 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1825,7 +1825,7 @@ static void make_uffd_wp_pte(struct vm_area_struct *vma,
pte_t old_pte;
old_pte = ptep_modify_prot_start(vma, addr, pte);
- ptent = pte_mkuffd_wp(ptent);
+ ptent = pte_mkuffd_wp(old_pte);
ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent);
} else if (is_swap_pte(ptent)) {
ptent = pte_swp_mkuffd_wp(ptent);
--
2.25.1
Powered by blists - more mailing lists