diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-03-03 13:12:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-03-03 13:12:14 -0500 |
commit | a64e715fc74b1a7dcc5944f848acc38b2c4d4ee2 (patch) | |
tree | 6a5dfc2b0ff946406082a8ad4dc046964d259dea /fs/exec.c | |
parent | a345b4ba2086bacc63884e5d72268415a97bcbff (diff) |
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 b6a2fea39318e43fee84fa7b0b90d68bed92d2ba ("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: Carlos 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: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/exec.c')
-rw-r--r-- | fs/exec.c | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -173,8 +173,15 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
173 | return NULL; | 173 | return NULL; |
174 | 174 | ||
175 | if (write) { | 175 | if (write) { |
176 | struct rlimit *rlim = current->signal->rlim; | ||
177 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 176 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
177 | struct rlimit *rlim; | ||
178 | |||
179 | /* | ||
180 | * We've historically supported up to 32 pages (ARG_MAX) | ||
181 | * of argument strings even with small stacks | ||
182 | */ | ||
183 | if (size <= ARG_MAX) | ||
184 | return page; | ||
178 | 185 | ||
179 | /* | 186 | /* |
180 | * Limit to 1/4-th the stack size for the argv+env strings. | 187 | * 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 | * - the program will have a reasonable amount of stack left | 190 | * - the program will have a reasonable amount of stack left |
184 | * to work from. | 191 | * to work from. |
185 | */ | 192 | */ |
193 | rlim = current->signal->rlim; | ||
186 | if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { | 194 | if (size > rlim[RLIMIT_STACK].rlim_cur / 4) { |
187 | put_page(page); | 195 | put_page(page); |
188 | return NULL; | 196 | return NULL; |