mm/vmalloc.c: avoid endless loop under v[un]mapping improper ranges
Subsystems (2)
PATCH 5/5 mm/vmalloc.c: avoid endless loop under v[un]mapping improper ranges
From: zijun_hu <[email protected]>
fix the following bug:
- endless loop maybe happen when v[un]mapping improper ranges whose either boundary is not aligned to page
Signed-off-by zijun_hu <[email protected]>
--- mm/vmalloc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
mm/vmalloc.c +7 -2
@@ -67,7 +67,7 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)do {pte_t ptent =ptep_get_and_clear (&init_mm, addr, pte);WARN_ON (!pte_none (ptent) && !pte_present (ptent)); - }while (pte++, addr +=PAGE_SIZE , addr != end); + }while (pte++, addr +=PAGE_SIZE , addr < end && addr >=PAGE_SIZE ); }static void vunmap_pmd_range (pud_t *pud,unsigned long addr,unsigned long end)
@@ -108,6 +108,9 @@ static void vunmap_page_range(unsigned long addr, unsigned long end)unsigned long next;BUG_ON (addr >= end); +WARN_ON (!PAGE_ALIGNED (addr) || !PAGE_ALIGNED (end)); + + addr =round_down (addr,PAGE_SIZE ); pgd =pgd_offset_k (addr); do { next = pgd_addr_end(addr, end);
@@ -139,7 +142,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,return -ENOMEM ;set_pte_at (&init_mm, addr, pte,mk_pte (page, prot)); (*nr)++; - }while (pte++, addr +=PAGE_SIZE , addr != end); + }while (pte++, addr +=PAGE_SIZE , addr < end);return 0 ; }
@@ -193,6 +196,8 @@ static int vmap_page_range_noflush(unsigned long start, unsigned long end,int nr =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);
Signature · 1 line
1.9.1
Quoted 45 lines · zijun_hu
From:
zijun_hu<[email protected]>fix the following bug:
- endless loop maybe happen when v[un]mapping improper ranges whose either boundary is not aligned to pageSigned-off-by zijun_hu <[email protected]>--- mm/vmalloc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)mm/vmalloc.c +5
-2@@ -67,7 +67,7 @@ static void vunmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end)do {pte_t ptent =ptep_get_and_clear (&init_mm, addr, pte);WARN_ON (!pte_none (ptent) && !pte_present (ptent)); - }while (pte++, addr +=PAGE_SIZE , addr != end); + }while (pte++, addr +=PAGE_SIZE , addr < end && addr >=PAGE_SIZE ); }static void vunmap_pmd_range (pud_t *pud,unsigned long addr,unsigned long end)@@ -108,6 +108,9 @@ static void vunmap_page_range(unsigned long addr, unsigned long end)unsigned long next;BUG_ON (addr >= end); +WARN_ON (!PAGE_ALIGNED (addr) || !PAGE_ALIGNED (end)); + + addr =round_down (addr,PAGE_SIZE ); pgd =pgd_offset_k (addr); do { next = pgd_addr_end(addr, end);@@ -139,7 +142,7 @@ static int vmap_pte_range(pmd_t *pmd, unsigned long addr,return -ENOMEM ;set_pte_at (&init_mm, addr, pte,mk_pte (page, prot)); (*nr)++; - }while (pte++, addr +=PAGE_SIZE , addr != end); + }while (pte++, addr +=PAGE_SIZE , addr < end);return 0 ; }
mm/vmalloc.c static int vmap_page_range_noflush(unsigned long start, unsigned long end, · line 203
Quoted 8 lines
mm/vmalloc.c +2
-0@@ -193,6 +196,8 @@ static int vmap_page_range_noflush(unsigned long start, unsigned long end,int nr =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);
From: zijun_hu <[email protected]>
s/WARN_ON()/WARN_ON_ONCE()/ to reduce warning messages
Signed-off-by zijun_hu <[email protected]>
--- mm/vmalloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/vmalloc.c +1 -1
@@ -108,7 +108,7 @@ static void vunmap_page_range(unsigned long addr, unsigned long end)unsigned long next;BUG_ON (addr >= end); -WARN_ON (!PAGE_ALIGNED (addr) || !PAGE_ALIGNED (end)); +WARN_ON_ONCE (!PAGE_ALIGNED (addr) || !PAGE_ALIGNED (end)); addr =round_down (addr,PAGE_SIZE ); pgd =pgd_offset_k (addr);
Signature · 1 line
1.9.1