From: Mitchell Blank Jr If SELECT_STACK_ALLOC is not a multiple of sizeof(long) then stack_fds[] would be shorter than SELECT_STACK_ALLOC bytes and could overflow later in the function. Fixed by simply rearranging the test later to work on sizeof(stack_fds) Currently SELECT_STACK_ALLOC is 256 so this doesn't happen, but it's nasty to have things like this hidden in the code. What if later someone decides to change SELECT_STACK_ALLOC to 300? Signed-off-by: Mitchell Blank Jr Signed-off-by: Andrew Morton --- fs/select.c | 16 +++++++++------- 1 files changed, 9 insertions(+), 7 deletions(-) diff -puN fs/select.c~select-dont-overflow-if-select_stack_alloc-%-sizeoflong-=-0 fs/select.c --- 25/fs/select.c~select-dont-overflow-if-select_stack_alloc-%-sizeoflong-=-0 Mon Apr 3 16:14:49 2006 +++ 25-akpm/fs/select.c Mon Apr 3 16:14:49 2006 @@ -311,7 +311,8 @@ static int core_sys_select(int n, fd_set { fd_set_bits fds; void *bits; - int ret, size, max_fdset; + int ret, max_fdset; + unsigned int size; struct fdtable *fdt; /* Allocate small arguments on the stack to save memory and be faster */ long stack_fds[SELECT_STACK_ALLOC/sizeof(long)]; @@ -333,14 +334,15 @@ static int core_sys_select(int n, fd_set * since we used fdset we need to allocate memory in units of * long-words. */ - ret = -ENOMEM; size = FDS_BYTES(n); - if (6*size < SELECT_STACK_ALLOC) - bits = stack_fds; - else + bits = stack_fds; + 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 (!bits) - goto out_nofds; + if (!bits) + goto out_nofds; + } fds.in = bits; fds.out = bits + size; fds.ex = bits + 2*size; _