]> git.ipfire.org Git - people/ms/linux.git/commitdiff
mm/madvise: fix potential pte_unmap_unlock pte error
authorMiaohe Lin <linmiaohe@huawei.com>
Fri, 29 Apr 2022 06:16:09 +0000 (23:16 -0700)
committerakpm <akpm@linux-foundation.org>
Fri, 29 Apr 2022 06:16:09 +0000 (23:16 -0700)
We can't assume pte_offset_map_lock will return same orig_pte value. So
it's necessary to reacquire the orig_pte or pte_unmap_unlock will unmap
the stale pte.

Link: https://lkml.kernel.org/r/20220416081416.23304-1-linmiaohe@huawei.com
Fixes: 9c276cc65a58 ("mm: introduce MADV_COLD")
Fixes: 854e9ed09ded ("mm: support madvise(MADV_FREE)")
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Hugh Dickins <hughd@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/madvise.c

index 1873616a37d2efffbe49804eb498808377d7fa5f..c965fac7b13a3e682650a60f49a106a83284ed09 100644 (file)
@@ -432,12 +432,12 @@ regular_page:
                        if (split_huge_page(page)) {
                                unlock_page(page);
                                put_page(page);
-                               pte_offset_map_lock(mm, pmd, addr, &ptl);
+                               orig_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
                                break;
                        }
                        unlock_page(page);
                        put_page(page);
-                       pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+                       orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
                        pte--;
                        addr -= PAGE_SIZE;
                        continue;
@@ -648,12 +648,12 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
                        if (split_huge_page(page)) {
                                unlock_page(page);
                                put_page(page);
-                               pte_offset_map_lock(mm, pmd, addr, &ptl);
+                               orig_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
                                goto out;
                        }
                        unlock_page(page);
                        put_page(page);
-                       pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+                       orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
                        pte--;
                        addr -= PAGE_SIZE;
                        continue;