The PTE loop of the unmap path stops only at addr == end.  With an
unaligned end addr never lands on end, so the loop walks past the
range and keeps clearing.  With an unaligned start the loop begins
in the page containing start, which extends below the range.  Either
way the unmap clears the mappings adjacent to the range, and that is
nearly impossible to debug afterwards.

vmap only installs page-aligned, page-granular mappings, so an
unaligned unmap request is never a legitimate teardown, and there is
no way to tell which pages the caller meant.  Check addr and end at
the entry of __vunmap_range_noflush() and bug out before any PTE is
cleared.

Signed-off-by: Hao Ge <[email protected]>
---
 mm/vmalloc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 86fbb1d2b27a..0565cbfe325c 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -518,6 +518,8 @@ void __vunmap_range_noflush(unsigned long start, unsigned 
long end)
        pgtbl_mod_mask mask = 0;
 
        BUG_ON(addr >= end);
+       BUG_ON(!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(end));
+
        pgd = pgd_offset_k(addr);
        do {
                next = pgd_addr_end(addr, end);
-- 
2.25.1


Reply via email to