]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commit
mm: pagewalk: Fix race between unmap and page walker
authorSteven Price <steven.price@arm.com>
Fri, 2 Sep 2022 11:26:12 +0000 (12:26 +0100)
committerStefan Bader <stefan.bader@canonical.com>
Wed, 23 Nov 2022 14:10:55 +0000 (15:10 +0100)
commit59b5159300b55c62ad34feafcb9a5dc7fcab2d1c
treecb10519a2a68983fb3c70d1630f6881b45217740
parentf12c2f5bdd9761aa8fd799da9f99f441a7f15ddd
mm: pagewalk: Fix race between unmap and page walker

BugLink: https://bugs.launchpad.net/bugs/1991840
[ Upstream commit 8782fb61cc848364e1e1599d76d3c9dd58a1cc06 ]

The mmap lock protects the page walker from changes to the page tables
during the walk.  However a read lock is insufficient to protect those
areas which don't have a VMA as munmap() detaches the VMAs before
downgrading to a read lock and actually tearing down PTEs/page tables.

For users of walk_page_range() the solution is to simply call pte_hole()
immediately without checking the actual page tables when a VMA is not
present. We now never call __walk_page_range() without a valid vma.

For walk_page_range_novma() the locking requirements are tightened to
require the mmap write lock to be taken, and then walking the pgd
directly with 'no_vma' set.

This in turn means that all page walkers either have a valid vma, or
it's that special 'novma' case for page table debugging.  As a result,
all the odd '(!walk->vma && !walk->no_vma)' tests can be removed.

Fixes: dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap")
Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Steven Price <steven.price@arm.com>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
arch/riscv/mm/pageattr.c
mm/pagewalk.c
mm/ptdump.c