summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-03-28 21:29:38 +0200
committerAdrian Bunk <bunk@stusta.de>2007-03-28 21:29:38 +0200
commit921e8ebfc8b0e41dc724ea52f4b95b7c44f6e880 (patch)
treefd6779c379ac22493f2016d402e0f38bd4dc3aa4
parentef1136fb7497e0ad6b419add0b463c9a770c42ee (diff)
mm: fix madvise infinine loop
madvise(MADV_REMOVE) can go into an infinite loop or cause an oops if the call covers a region from the start of a vma, and extending past that vma. Signed-off-by: Nick Piggin <npiggin@suse.de> Acked-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Adrian Bunk <bunk@stusta.de>
-rw-r--r--mm/madvise.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/mm/madvise.c b/mm/madvise.c
index 4e196155a0c3..77916e9fc52b 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -155,11 +155,14 @@ static long madvise_dontneed(struct vm_area_struct * vma,
* Other filesystems return -ENOSYS.
*/
static long madvise_remove(struct vm_area_struct *vma,
+ struct vm_area_struct **prev,
unsigned long start, unsigned long end)
{
struct address_space *mapping;
loff_t offset, endoff;
+ *prev = vma;
+
if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB))
return -EINVAL;
@@ -199,7 +202,7 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
error = madvise_behavior(vma, prev, start, end, behavior);
break;
case MADV_REMOVE:
- error = madvise_remove(vma, start, end);
+ error = madvise_remove(vma, prev, start, end);
break;
case MADV_WILLNEED: