summaryrefslogtreecommitdiff
path: root/fs/select.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-11 17:34:10 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-11 17:34:10 -0700
commita379f71a30dddbd2e7393624e455ce53c87965d1 (patch)
treec9c71b3eb19ff7e8618ff29e9d5ac99882b823e1 /fs/select.c
parentde34f4da7f62ff59ac6e1ef320b0fcfa3296fce3 (diff)
parent9c5d760b8d229b94c5030863a5edaee5f1a9d7b7 (diff)
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton: - a few block updates that fell in my lap - lib/ updates - checkpatch - autofs - ipc - a ton of misc other things * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (100 commits) mm: split gfp_mask and mapping flags into separate fields fs: use mapping_set_error instead of opencoded set_bit treewide: remove redundant #include <linux/kconfig.h> hung_task: allow hung_task_panic when hung_task_warnings is 0 kthread: add kerneldoc for kthread_create() kthread: better support freezable kthread workers kthread: allow to modify delayed kthread work kthread: allow to cancel kthread work kthread: initial support for delayed kthread work kthread: detect when a kthread work is used by more workers kthread: add kthread_destroy_worker() kthread: add kthread_create_worker*() kthread: allow to call __kthread_create_on_node() with va_list args kthread/smpboot: do not park in kthread_create_on_cpu() kthread: kthread worker API cleanup kthread: rename probe_kthread_data() to kthread_probe_data() scripts/tags.sh: enable code completion in VIM mm: kmemleak: avoid using __va() on addresses that don't have a lowmem mapping kdump, vmcoreinfo: report memory sections virtual addresses ipc/sem.c: add cond_resched in exit_sme ...
Diffstat (limited to 'fs/select.c')
-rw-r--r--fs/select.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/fs/select.c b/fs/select.c
index 8ed9da50896a..3d4f85defeab 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -29,6 +29,7 @@
#include <linux/sched/rt.h>
#include <linux/freezer.h>
#include <net/busy_poll.h>
+#include <linux/vmalloc.h>
#include <asm/uaccess.h>
@@ -554,7 +555,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
fd_set_bits fds;
void *bits;
int ret, max_fds;
- unsigned int size;
+ size_t size, alloc_size;
struct fdtable *fdt;
/* Allocate small arguments on the stack to save memory and be faster */
long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
@@ -581,7 +582,14 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
if (size > sizeof(stack_fds) / 6) {
/* Not enough space in on-stack array; must use kmalloc */
ret = -ENOMEM;
- bits = kmalloc(6 * size, GFP_KERNEL);
+ if (size > (SIZE_MAX / 6))
+ goto out_nofds;
+
+ alloc_size = 6 * size;
+ bits = kmalloc(alloc_size, GFP_KERNEL|__GFP_NOWARN);
+ if (!bits && alloc_size > PAGE_SIZE)
+ bits = vmalloc(alloc_size);
+
if (!bits)
goto out_nofds;
}
@@ -618,7 +626,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
out:
if (bits != stack_fds)
- kfree(bits);
+ kvfree(bits);
out_nofds:
return ret;
}