Skip to content

Commit

Permalink
mm/mlock: fix vma iterator conversion of apply_vma_lock_flags()
Browse files Browse the repository at this point in the history
apply_vma_lock_flags() calls mlock_fixup(), which could merge the VMA
after where the vma iterator is located.  Although this is not an issue,
the next iteration of the loop will check the start of the vma to be equal
to the locally saved 'tmp' variable and cause an incorrect failure
scenario.  Fix the error by setting tmp to the end of the vma iterator
value before restarting the loop.

There is also a potential of the error code being overwritten when the
loop terminates early.  Fix the return issue by directly returning when an
error is encountered since there is nothing to undo after the loop.

Link: https://lkml.kernel.org/r/[email protected]
Fixes: 37598f5 ("mlock: convert mlock to vma iterator")
Signed-off-by: Liam R. Howlett <[email protected]>
Reported-by: Ryan Roberts <[email protected]>
  Link: https://lore.kernel.org/linux-mm/[email protected]/
Tested-by: Ryan Roberts <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
  • Loading branch information
howlett authored and akpm00 committed Jul 17, 2023
1 parent 636e348 commit 2658f94
Showing 1 changed file with 5 additions and 4 deletions.
9 changes: 5 additions & 4 deletions mm/mlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,6 @@ static int apply_vma_lock_flags(unsigned long start, size_t len,
{
unsigned long nstart, end, tmp;
struct vm_area_struct *vma, *prev;
int error;
VMA_ITERATOR(vmi, current->mm, start);

VM_BUG_ON(offset_in_page(start));
Expand All @@ -498,6 +497,7 @@ static int apply_vma_lock_flags(unsigned long start, size_t len,
nstart = start;
tmp = vma->vm_start;
for_each_vma_range(vmi, vma, end) {
int error;
vm_flags_t newflags;

if (vma->vm_start != tmp)
Expand All @@ -511,14 +511,15 @@ static int apply_vma_lock_flags(unsigned long start, size_t len,
tmp = end;
error = mlock_fixup(&vmi, vma, &prev, nstart, tmp, newflags);
if (error)
break;
return error;
tmp = vma_iter_end(&vmi);
nstart = tmp;
}

if (vma_iter_end(&vmi) < end)
if (tmp < end)
return -ENOMEM;

return error;
return 0;
}

/*
Expand Down

0 comments on commit 2658f94

Please sign in to comment.