summaryrefslogtreecommitdiffstats
path: root/fs/select.c
diff options
context:
space:
mode:
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 @@
29#include <linux/sched/rt.h> 29#include <linux/sched/rt.h>
30#include <linux/freezer.h> 30#include <linux/freezer.h>
31#include <net/busy_poll.h> 31#include <net/busy_poll.h>
32#include <linux/vmalloc.h>
32 33
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
34 35
@@ -554,7 +555,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
554 fd_set_bits fds; 555 fd_set_bits fds;
555 void *bits; 556 void *bits;
556 int ret, max_fds; 557 int ret, max_fds;
557 unsigned int size; 558 size_t size, alloc_size;
558 struct fdtable *fdt; 559 struct fdtable *fdt;
559 /* Allocate small arguments on the stack to save memory and be faster */ 560 /* Allocate small arguments on the stack to save memory and be faster */
560 long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; 561 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,
581 if (size > sizeof(stack_fds) / 6) { 582 if (size > sizeof(stack_fds) / 6) {
582 /* Not enough space in on-stack array; must use kmalloc */ 583 /* Not enough space in on-stack array; must use kmalloc */
583 ret = -ENOMEM; 584 ret = -ENOMEM;
584 bits = kmalloc(6 * size, GFP_KERNEL); 585 if (size > (SIZE_MAX / 6))
586 goto out_nofds;
587
588 alloc_size = 6 * size;
589 bits = kmalloc(alloc_size, GFP_KERNEL|__GFP_NOWARN);
590 if (!bits && alloc_size > PAGE_SIZE)
591 bits = vmalloc(alloc_size);
592
585 if (!bits) 593 if (!bits)
586 goto out_nofds; 594 goto out_nofds;
587 } 595 }
@@ -618,7 +626,7 @@ int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
618 626
619out: 627out:
620 if (bits != stack_fds) 628 if (bits != stack_fds)
621 kfree(bits); 629 kvfree(bits);
622out_nofds: 630out_nofds:
623 return ret; 631 return ret;
624} 632}