summaryrefslogtreecommitdiffstats
path: root/mm/madvise.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2009-06-17 00:32:38 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2009-06-17 04:47:40 +0200
commit75927af8bcb940dad4fe281713d526cb520869ff (patch)
tree96b2b903ce215d3c47204b7b77724c9fa0aa6502 /mm/madvise.c
parentpage-allocator: warn if __GFP_NOFAIL is used for a large allocation (diff)
downloadlinux-75927af8bcb940dad4fe281713d526cb520869ff.tar.xz
linux-75927af8bcb940dad4fe281713d526cb520869ff.zip
mm: madvise(): correct return code
The posix_madvise() function succeeds (and does nothing) when called with parameters (NULL, 0, -1); according to LSB tests, it should fail with EINVAL because -1 is not a valid flag. When called with a valid address and size, it correctly fails. So perform an initial check for valid flags first. Reported-by: Jiri Dluhos <jdluhos@novell.com> Signed-off-by: Nick Piggin <npiggin@suse.de> Reviewed-and-Tested-by: WANG Cong <xiyou.wangcong@gmail.com> Cc: Michael Kerrisk <mtk.manpages@googlemail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/madvise.c')
-rw-r--r--mm/madvise.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/mm/madvise.c b/mm/madvise.c
index e994dcb479d6..76eb4193acdd 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -238,12 +238,30 @@ madvise_vma(struct vm_area_struct *vma, struct vm_area_struct **prev,
break;
default:
- error = -EINVAL;
+ BUG();
break;
}
return error;
}
+static int
+madvise_behavior_valid(int behavior)
+{
+ switch (behavior) {
+ case MADV_DOFORK:
+ case MADV_DONTFORK:
+ case MADV_NORMAL:
+ case MADV_SEQUENTIAL:
+ case MADV_RANDOM:
+ case MADV_REMOVE:
+ case MADV_WILLNEED:
+ case MADV_DONTNEED:
+ return 1;
+
+ default:
+ return 0;
+ }
+}
/*
* The madvise(2) system call.
*
@@ -289,6 +307,9 @@ SYSCALL_DEFINE3(madvise, unsigned long, start, size_t, len_in, int, behavior)
int write;
size_t len;
+ if (!madvise_behavior_valid(behavior))
+ return error;
+
write = madvise_need_mmap_write(behavior);
if (write)
down_write(&current->mm->mmap_sem);