Commit a64e715f authored by Linus Torvalds's avatar Linus Torvalds

Allow ARG_MAX execve string space even with a small stack limit

The new code that removed the limitation on the execve string size
(which was historically 32 pages) replaced it with a much softer limit
based on RLIMIT_STACK which is usually much larger than the traditional
limit.  See commit b6a2fea3 ("mm:
variable length argument support") for details.

However, if you have a small stack limit (perhaps because you need lots
of stacks in a threaded environment), the new heuristic of allowing up
to 1/4th of RLIMIT_STACK to be used for argument and environment strings
could actually be smaller than the old limit.

So just say that it's ok to have up to ARG_MAX strings regardless of the
value of RLIMIT_STACK, and check the rlimit only when going over that
traditional limit.

(Of course, if you actually have a *really* small stack limit, the whole
stack itself will be limited before you hit ARG_MAX, but that has always
been true and is clearly the right behaviour anyway).
Acked-by: default avatarCarlos O'Donell <carlos@codesourcery.com>
Cc: Michael Kerrisk <michael.kerrisk@googlemail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ollie Wild <aaw@google.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a345b4ba
...@@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, ...@@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
return NULL; return NULL;
if (write) { if (write) {
struct rlimit *rlim = current->signal->rlim;
unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start;
struct rlimit *rlim;
/*
* We've historically supported up to 32 pages (ARG_MAX)
* of argument strings even with small stacks
*/
if (size <= ARG_MAX)
return page;
/* /*
* Limit to 1/4-th the stack size for the argv+env strings. * Limit to 1/4-th the stack size for the argv+env strings.
...@@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, ...@@ -183,6 +190,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
* - the program will have a reasonable amount of stack left * - the program will have a reasonable amount of stack left
* to work from. * to work from.
*/ */
rlim = current->signal->rlim;
if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { if (size > rlim[RLIMIT_STACK].rlim_cur / 4) {
put_page(page); put_page(page);
return NULL; return NULL;
......
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