Skip to content

Commit 7329e3e

Browse files
howlettakpm00
authored andcommitted
mm/mempolicy: fix mbind_range() arguments to vma_merge()
Fuzzing produced an invalid argument to vma_merge() which was caught by the newly added verification of the number of VMAs being removed on process exit. Analyzing the failure eventually resulted in finding an issue with the search of a VMA that started at address 0, which caused an underflow and thus the loss of many VMAs being tracked in the tree. Fix the underflow by changing the search of the maple tree to use the start address directly. Link: https://lkml.kernel.org/r/[email protected] Fixes: 66850be ("mm/mempolicy: use vma iterator & maple state instead of vma linked list") Signed-off-by: Liam R. Howlett <[email protected]> Reported-by: kernel test robot <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: Yu Zhao <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent cef408e commit 7329e3e

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

mm/mempolicy.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -787,17 +787,22 @@ static int vma_replace_policy(struct vm_area_struct *vma,
787787
static int mbind_range(struct mm_struct *mm, unsigned long start,
788788
unsigned long end, struct mempolicy *new_pol)
789789
{
790-
MA_STATE(mas, &mm->mm_mt, start - 1, start - 1);
790+
MA_STATE(mas, &mm->mm_mt, start, start);
791791
struct vm_area_struct *prev;
792792
struct vm_area_struct *vma;
793793
int err = 0;
794794
pgoff_t pgoff;
795795

796-
prev = mas_find_rev(&mas, 0);
797-
if (prev && (start < prev->vm_end))
798-
vma = prev;
799-
else
800-
vma = mas_next(&mas, end - 1);
796+
prev = mas_prev(&mas, 0);
797+
if (unlikely(!prev))
798+
mas_set(&mas, start);
799+
800+
vma = mas_find(&mas, end - 1);
801+
if (WARN_ON(!vma))
802+
return 0;
803+
804+
if (start > vma->vm_start)
805+
prev = vma;
801806

802807
for (; vma; vma = mas_next(&mas, end - 1)) {
803808
unsigned long vmstart = max(start, vma->vm_start);

0 commit comments

Comments
 (0)