X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fexec.c;h=1554e549c1de4102e2c1e3044d18939075671e20;hb=cea299eb189fca09c413432b807abd607385b3bc;hp=a0006d85785c991676a3719a36abdd9b887397fd;hpb=b1bf6857ac304ee1c05cb3d804f70312e947887c;p=pandora-kernel.git diff --git a/fs/exec.c b/fs/exec.c index a0006d85785c..1554e549c1de 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -207,8 +208,26 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, if (write) { unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; + unsigned long ptr_size; struct rlimit *rlim; + /* + * Since the stack will hold pointers to the strings, we + * must account for them as well. + * + * The size calculation is the entire vma while each arg page is + * built, so each time we get here it's calculating how far it + * is currently (rather than each call being just the newly + * added size from the arg page). As a result, we need to + * always add the entire size of the pointers, so that on the + * last call to get_arg_page() we'll actually have the entire + * correct size. + */ + ptr_size = (bprm->argc + bprm->envc) * sizeof(void *); + if (ptr_size > ULONG_MAX - size) + goto fail; + size += ptr_size; + acct_arg_size(bprm, size / PAGE_SIZE); /* @@ -226,13 +245,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, * to work from. */ rlim = current->signal->rlim; - if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) { - put_page(page); - return NULL; - } + if (size > ACCESS_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) + goto fail; } return page; + +fail: + put_page(page); + return NULL; } static void put_arg_page(struct page *page) @@ -1974,8 +1995,11 @@ static int coredump_wait(int exit_code, struct core_state *core_state) complete(vfork_done); } - if (core_waiters) + if (core_waiters > 0) { + freezer_do_not_count(); wait_for_completion(&core_state->startup); + freezer_count(); + } fail: return core_waiters; }