Skip to content

Commit e495dd3

Browse files
Hugh DickinsLinus Torvalds
authored andcommitted
[PATCH] mm: vma_adjust adjust_next wrap
Fix vma_adjust adjust_next wrapping: Rajesh V. pointed out that if end were 2GB or more beyond next->vm_start (on 32-bit), then next->vm_pgoff would have been negatively adjusted. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Rajesh Venkatasubramanian <vrajesh@umich.edu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent ad6e519 commit e495dd3

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

mm/mmap.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -373,20 +373,27 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start,
373373

374374
if (next && !insert) {
375375
if (end >= next->vm_end) {
376+
/*
377+
* vma expands, overlapping all the next, and
378+
* perhaps the one after too (mprotect case 6).
379+
*/
376380
again: remove_next = 1 + (end > next->vm_end);
377381
end = next->vm_end;
378382
anon_vma = next->anon_vma;
379-
} else if (end < vma->vm_end || end > next->vm_start) {
383+
} else if (end > next->vm_start) {
380384
/*
381-
* vma shrinks, and !insert tells it's not
382-
* split_vma inserting another: so it must
383-
* be mprotect shifting the boundary down.
384-
* Or:
385385
* vma expands, overlapping part of the next:
386-
* must be mprotect shifting the boundary up.
386+
* mprotect case 5 shifting the boundary up.
387+
*/
388+
adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
389+
anon_vma = next->anon_vma;
390+
} else if (end < vma->vm_end) {
391+
/*
392+
* vma shrinks, and !insert tells it's not
393+
* split_vma inserting another: so it must be
394+
* mprotect case 4 shifting the boundary down.
387395
*/
388-
BUG_ON(vma->vm_end != next->vm_start);
389-
adjust_next = end - next->vm_start;
396+
adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
390397
anon_vma = next->anon_vma;
391398
}
392399
}
@@ -418,8 +425,8 @@ again: remove_next = 1 + (end > next->vm_end);
418425
vma->vm_end = end;
419426
vma->vm_pgoff = pgoff;
420427
if (adjust_next) {
421-
next->vm_start += adjust_next;
422-
next->vm_pgoff += adjust_next >> PAGE_SHIFT;
428+
next->vm_start += adjust_next << PAGE_SHIFT;
429+
next->vm_pgoff += adjust_next;
423430
}
424431

425432
if (root) {

0 commit comments

Comments
 (0)