diff options
author | Kees Cook <keescook@chromium.org> | 2017-07-07 14:57:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-07 23:05:08 -0400 |
commit | da029c11e6b12f321f36dac8771e833b65cec962 (patch) | |
tree | 0ba6e0c9338f1b3de6498793ecff2643c4fd289c | |
parent | 088737f44bbf6378745f5b57b035e57ee3dc4750 (diff) |
exec: Limit arg stack to at most 75% of _STK_LIM
To avoid pathological stack usage or the need to special-case setuid
execs, just limit all arg stack usage to at most 75% of _STK_LIM (6MB).
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/exec.c | 11 |
1 files changed, 6 insertions, 5 deletions
@@ -220,8 +220,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
220 | 220 | ||
221 | if (write) { | 221 | if (write) { |
222 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; | 222 | unsigned long size = bprm->vma->vm_end - bprm->vma->vm_start; |
223 | unsigned long ptr_size; | 223 | unsigned long ptr_size, limit; |
224 | struct rlimit *rlim; | ||
225 | 224 | ||
226 | /* | 225 | /* |
227 | * Since the stack will hold pointers to the strings, we | 226 | * Since the stack will hold pointers to the strings, we |
@@ -250,14 +249,16 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos, | |||
250 | return page; | 249 | return page; |
251 | 250 | ||
252 | /* | 251 | /* |
253 | * Limit to 1/4-th the stack size for the argv+env strings. | 252 | * Limit to 1/4 of the max stack size or 3/4 of _STK_LIM |
253 | * (whichever is smaller) for the argv+env strings. | ||
254 | * This ensures that: | 254 | * This ensures that: |
255 | * - the remaining binfmt code will not run out of stack space, | 255 | * - the remaining binfmt code will not run out of stack space, |
256 | * - the program will have a reasonable amount of stack left | 256 | * - the program will have a reasonable amount of stack left |
257 | * to work from. | 257 | * to work from. |
258 | */ | 258 | */ |
259 | rlim = current->signal->rlim; | 259 | limit = _STK_LIM / 4 * 3; |
260 | if (size > READ_ONCE(rlim[RLIMIT_STACK].rlim_cur) / 4) | 260 | limit = min(limit, rlimit(RLIMIT_STACK) / 4); |
261 | if (size > limit) | ||
261 | goto fail; | 262 | goto fail; |
262 | } | 263 | } |
263 | 264 | ||