Commit 5d1854e1 authored by Eric Sandeen's avatar Eric Sandeen Committed by Linus Torvalds

[PATCH] reject corrupt swapfiles earlier

The fsfuzzer found this; with a corrupt small swapfile that claims to have
many pages:

  [root]# file swap.741.img
  swap.741.img: Linux/i386 swap file (new style) 1 (4K pages) size 1040191487 pages
  [root]# ls -l swap.741.img
  -rw-r--r-- 1 root root 16777216 Nov 22 05:18 swap.741.img

sys_swapon() will try to vmalloc all those pages, and -then- check to see if
the file is actually that large:

                if (!(p->swap_map = vmalloc(maxpages * sizeof(short)))) {
  <snip>
        if (swapfilesize && maxpages > swapfilesize) {
                printk(KERN_WARNING
                       "Swap area shorter than signature indicates\n");

It seems to me that it would make more sense to move this test up before
the vmalloc, with the other checks, to avoid the OOM-killer in this
situation...
Signed-off-by: default avatarEric Sandeen <sandeen@redhat.com>
Cc: Hugh Dickins <hugh@veritas.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 4af2bfc1
...@@ -1552,6 +1552,11 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) ...@@ -1552,6 +1552,11 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
error = -EINVAL; error = -EINVAL;
if (!maxpages) if (!maxpages)
goto bad_swap; goto bad_swap;
if (swapfilesize && maxpages > swapfilesize) {
printk(KERN_WARNING
"Swap area shorter than signature indicates\n");
goto bad_swap;
}
if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode))
goto bad_swap; goto bad_swap;
if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
...@@ -1579,12 +1584,6 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags) ...@@ -1579,12 +1584,6 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
goto bad_swap; goto bad_swap;
} }
if (swapfilesize && maxpages > swapfilesize) {
printk(KERN_WARNING
"Swap area shorter than signature indicates\n");
error = -EINVAL;
goto bad_swap;
}
if (nr_good_pages) { if (nr_good_pages) {
p->swap_map[0] = SWAP_MAP_BAD; p->swap_map[0] = SWAP_MAP_BAD;
p->max = maxpages; p->max = maxpages;
......
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