Commit e495dd35 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

[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: default avatarHugh Dickins <hugh@veritas.com>
Signed-off-by: default avatarRajesh Venkatasubramanian <vrajesh@umich.edu>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ad6e519b
...@@ -373,20 +373,27 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start, ...@@ -373,20 +373,27 @@ void vma_adjust(struct vm_area_struct *vma, unsigned long start,
if (next && !insert) { if (next && !insert) {
if (end >= next->vm_end) { if (end >= next->vm_end) {
/*
* vma expands, overlapping all the next, and
* perhaps the one after too (mprotect case 6).
*/
again: remove_next = 1 + (end > next->vm_end); again: remove_next = 1 + (end > next->vm_end);
end = next->vm_end; end = next->vm_end;
anon_vma = next->anon_vma; anon_vma = next->anon_vma;
} else if (end < vma->vm_end || end > next->vm_start) { } else if (end > next->vm_start) {
/* /*
* vma shrinks, and !insert tells it's not
* split_vma inserting another: so it must
* be mprotect shifting the boundary down.
* Or:
* vma expands, overlapping part of the next: * vma expands, overlapping part of the next:
* must be mprotect shifting the boundary up. * mprotect case 5 shifting the boundary up.
*/
adjust_next = (end - next->vm_start) >> PAGE_SHIFT;
anon_vma = next->anon_vma;
} else if (end < vma->vm_end) {
/*
* vma shrinks, and !insert tells it's not
* split_vma inserting another: so it must be
* mprotect case 4 shifting the boundary down.
*/ */
BUG_ON(vma->vm_end != next->vm_start); adjust_next = - ((vma->vm_end - end) >> PAGE_SHIFT);
adjust_next = end - next->vm_start;
anon_vma = next->anon_vma; anon_vma = next->anon_vma;
} }
} }
...@@ -418,8 +425,8 @@ again: remove_next = 1 + (end > next->vm_end); ...@@ -418,8 +425,8 @@ again: remove_next = 1 + (end > next->vm_end);
vma->vm_end = end; vma->vm_end = end;
vma->vm_pgoff = pgoff; vma->vm_pgoff = pgoff;
if (adjust_next) { if (adjust_next) {
next->vm_start += adjust_next; next->vm_start += adjust_next << PAGE_SHIFT;
next->vm_pgoff += adjust_next >> PAGE_SHIFT; next->vm_pgoff += adjust_next;
} }
if (root) { if (root) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment