|
@@ -257,7 +257,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
|
|
* to work from.
|
|
* to work from.
|
|
*/
|
|
*/
|
|
limit = _STK_LIM / 4 * 3;
|
|
limit = _STK_LIM / 4 * 3;
|
|
- limit = min(limit, rlimit(RLIMIT_STACK) / 4);
|
|
|
|
|
|
+ limit = min(limit, bprm->rlim_stack.rlim_cur / 4);
|
|
if (size > limit)
|
|
if (size > limit)
|
|
goto fail;
|
|
goto fail;
|
|
}
|
|
}
|
|
@@ -411,6 +411,11 @@ static int bprm_mm_init(struct linux_binprm *bprm)
|
|
if (!mm)
|
|
if (!mm)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
|
|
+ /* Save current stack limit for all calculations made during exec. */
|
|
|
|
+ task_lock(current->group_leader);
|
|
|
|
+ bprm->rlim_stack = current->signal->rlim[RLIMIT_STACK];
|
|
|
|
+ task_unlock(current->group_leader);
|
|
|
|
+
|
|
err = __bprm_mm_init(bprm);
|
|
err = __bprm_mm_init(bprm);
|
|
if (err)
|
|
if (err)
|
|
goto err;
|
|
goto err;
|
|
@@ -697,7 +702,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
|
|
|
|
|
|
#ifdef CONFIG_STACK_GROWSUP
|
|
#ifdef CONFIG_STACK_GROWSUP
|
|
/* Limit stack size */
|
|
/* Limit stack size */
|
|
- stack_base = rlimit_max(RLIMIT_STACK);
|
|
|
|
|
|
+ stack_base = bprm->rlim_stack.rlim_max;
|
|
if (stack_base > STACK_SIZE_MAX)
|
|
if (stack_base > STACK_SIZE_MAX)
|
|
stack_base = STACK_SIZE_MAX;
|
|
stack_base = STACK_SIZE_MAX;
|
|
|
|
|
|
@@ -770,7 +775,7 @@ int setup_arg_pages(struct linux_binprm *bprm,
|
|
* Align this down to a page boundary as expand_stack
|
|
* Align this down to a page boundary as expand_stack
|
|
* will align it up.
|
|
* will align it up.
|
|
*/
|
|
*/
|
|
- rlim_stack = rlimit(RLIMIT_STACK) & PAGE_MASK;
|
|
|
|
|
|
+ rlim_stack = bprm->rlim_stack.rlim_cur & PAGE_MASK;
|
|
#ifdef CONFIG_STACK_GROWSUP
|
|
#ifdef CONFIG_STACK_GROWSUP
|
|
if (stack_size + stack_expand > rlim_stack)
|
|
if (stack_size + stack_expand > rlim_stack)
|
|
stack_base = vma->vm_start + rlim_stack;
|
|
stack_base = vma->vm_start + rlim_stack;
|
|
@@ -1323,8 +1328,6 @@ EXPORT_SYMBOL(would_dump);
|
|
|
|
|
|
void setup_new_exec(struct linux_binprm * bprm)
|
|
void setup_new_exec(struct linux_binprm * bprm)
|
|
{
|
|
{
|
|
- struct rlimit rlim_stack;
|
|
|
|
-
|
|
|
|
/*
|
|
/*
|
|
* Once here, prepare_binrpm() will not be called any more, so
|
|
* Once here, prepare_binrpm() will not be called any more, so
|
|
* the final state of setuid/setgid/fscaps can be merged into the
|
|
* the final state of setuid/setgid/fscaps can be merged into the
|
|
@@ -1343,15 +1346,11 @@ void setup_new_exec(struct linux_binprm * bprm)
|
|
* RLIMIT_STACK, but after the point of no return to avoid
|
|
* RLIMIT_STACK, but after the point of no return to avoid
|
|
* needing to clean up the change on failure.
|
|
* needing to clean up the change on failure.
|
|
*/
|
|
*/
|
|
- if (current->signal->rlim[RLIMIT_STACK].rlim_cur > _STK_LIM)
|
|
|
|
- current->signal->rlim[RLIMIT_STACK].rlim_cur = _STK_LIM;
|
|
|
|
|
|
+ if (bprm->rlim_stack.rlim_cur > _STK_LIM)
|
|
|
|
+ bprm->rlim_stack.rlim_cur = _STK_LIM;
|
|
}
|
|
}
|
|
|
|
|
|
- task_lock(current->group_leader);
|
|
|
|
- rlim_stack = current->signal->rlim[RLIMIT_STACK];
|
|
|
|
- task_unlock(current->group_leader);
|
|
|
|
-
|
|
|
|
- arch_pick_mmap_layout(current->mm, &rlim_stack);
|
|
|
|
|
|
+ arch_pick_mmap_layout(current->mm, &bprm->rlim_stack);
|
|
|
|
|
|
current->sas_ss_sp = current->sas_ss_size = 0;
|
|
current->sas_ss_sp = current->sas_ss_size = 0;
|
|
|
|
|
|
@@ -1387,6 +1386,10 @@ EXPORT_SYMBOL(setup_new_exec);
|
|
/* Runs immediately before start_thread() takes over. */
|
|
/* Runs immediately before start_thread() takes over. */
|
|
void finalize_exec(struct linux_binprm *bprm)
|
|
void finalize_exec(struct linux_binprm *bprm)
|
|
{
|
|
{
|
|
|
|
+ /* Store any stack rlimit changes before starting thread. */
|
|
|
|
+ task_lock(current->group_leader);
|
|
|
|
+ current->signal->rlim[RLIMIT_STACK] = bprm->rlim_stack;
|
|
|
|
+ task_unlock(current->group_leader);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(finalize_exec);
|
|
EXPORT_SYMBOL(finalize_exec);
|
|
|
|
|