Commit 7d31ee9b authored by Denis Vlasenko's avatar Denis Vlasenko Committed by Linus Torvalds

[PATCH] reduce [compat_]do_execve stack usage

Allocating the 'struct linux_binprm' on the stack chews up too much
stackspace.

Just kmalloc it instead.
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent faf8ec06
......@@ -1368,7 +1368,7 @@ int compat_do_execve(char * filename,
compat_uptr_t __user *envp,
struct pt_regs * regs)
{
struct linux_binprm bprm;
struct linux_binprm *bprm;
struct file *file;
int retval;
int i;
......@@ -1381,86 +1381,86 @@ int compat_do_execve(char * filename,
sched_exec();
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
bprm.file = file;
bprm.filename = filename;
bprm.interp = filename;
bprm.sh_bang = 0;
bprm.loader = 0;
bprm.exec = 0;
bprm.interp_flags = 0;
bprm.interp_data = 0;
bprm.security = NULL;
bprm.mm = mm_alloc();
retval = -ENOMEM;
if (!bprm.mm)
bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
if (!bprm)
goto out_ret;
memset(bprm, 0, sizeof(*bprm));
bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
bprm->file = file;
bprm->filename = filename;
bprm->interp = filename;
bprm->mm = mm_alloc();
if (!bprm->mm)
goto out_file;
retval = init_new_context(current, bprm.mm);
retval = init_new_context(current, bprm->mm);
if (retval < 0)
goto out_mm;
bprm.argc = compat_count(argv, bprm.p / sizeof(compat_uptr_t));
if ((retval = bprm.argc) < 0)
bprm.argc = compat_count(argv, bprm->p / sizeof(compat_uptr_t));
if ((retval = bprm->argc) < 0)
goto out_mm;
bprm.envc = compat_count(envp, bprm.p / sizeof(compat_uptr_t));
if ((retval = bprm.envc) < 0)
bprm.envc = compat_count(envp, bprm->p / sizeof(compat_uptr_t));
if ((retval = bprm->envc) < 0)
goto out_mm;
retval = security_bprm_alloc(&bprm);
retval = security_bprm_alloc(bprm);
if (retval)
goto out;
retval = prepare_binprm(&bprm);
retval = prepare_binprm(bprm);
if (retval < 0)
goto out;
retval = copy_strings_kernel(1, &bprm.filename, &bprm);
retval = copy_strings_kernel(1, &bprm->filename, bprm);
if (retval < 0)
goto out;
bprm.exec = bprm.p;
retval = compat_copy_strings(bprm.envc, envp, &bprm);
bprm->exec = bprm->p;
retval = compat_copy_strings(bprm->envc, envp, bprm);
if (retval < 0)
goto out;
retval = compat_copy_strings(bprm.argc, argv, &bprm);
retval = compat_copy_strings(bprm->argc, argv, bprm);
if (retval < 0)
goto out;
retval = search_binary_handler(&bprm,regs);
retval = search_binary_handler(bprm, regs);
if (retval >= 0) {
free_arg_pages(&bprm);
free_arg_pages(bprm);
/* execve success */
security_bprm_free(&bprm);
security_bprm_free(bprm);
kfree(bprm);
return retval;
}
out:
/* Something went wrong, return the inode and free the argument pages*/
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
struct page * page = bprm.page[i];
struct page * page = bprm->page[i];
if (page)
__free_page(page);
}
if (bprm.security)
security_bprm_free(&bprm);
if (bprm->security)
security_bprm_free(bprm);
out_mm:
if (bprm.mm)
mmdrop(bprm.mm);
if (bprm->mm)
mmdrop(bprm->mm);
out_file:
if (bprm.file) {
allow_write_access(bprm.file);
fput(bprm.file);
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
}
kfree(bprm);
out_ret:
return retval;
}
......
......@@ -1092,7 +1092,7 @@ int do_execve(char * filename,
char __user *__user *envp,
struct pt_regs * regs)
{
struct linux_binprm bprm;
struct linux_binprm *bprm;
struct file *file;
int retval;
int i;
......@@ -1105,85 +1105,87 @@ int do_execve(char * filename,
sched_exec();
bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0]));
bprm.file = file;
bprm.filename = filename;
bprm.interp = filename;
bprm.interp_flags = 0;
bprm.interp_data = 0;
bprm.sh_bang = 0;
bprm.loader = 0;
bprm.exec = 0;
bprm.security = NULL;
bprm.mm = mm_alloc();
retval = -ENOMEM;
if (!bprm.mm)
bprm = kmalloc(sizeof(*bprm), GFP_KERNEL);
if (!bprm)
goto out_ret;
memset(bprm, 0, sizeof(*bprm));
bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
bprm->file = file;
bprm->filename = filename;
bprm->interp = filename;
bprm->mm = mm_alloc();
if (!bprm->mm)
goto out_file;
retval = init_new_context(current, bprm.mm);
retval = init_new_context(current, bprm->mm);
if (retval < 0)
goto out_mm;
bprm.argc = count(argv, bprm.p / sizeof(void *));
if ((retval = bprm.argc) < 0)
bprm->argc = count(argv, bprm->p / sizeof(void *));
if ((retval = bprm->argc) < 0)
goto out_mm;
bprm.envc = count(envp, bprm.p / sizeof(void *));
if ((retval = bprm.envc) < 0)
bprm->envc = count(envp, bprm->p / sizeof(void *));
if ((retval = bprm->envc) < 0)
goto out_mm;
retval = security_bprm_alloc(&bprm);
retval = security_bprm_alloc(bprm);
if (retval)
goto out;
retval = prepare_binprm(&bprm);
retval = prepare_binprm(bprm);
if (retval < 0)
goto out;
retval = copy_strings_kernel(1, &bprm.filename, &bprm);
retval = copy_strings_kernel(1, &bprm->filename, bprm);
if (retval < 0)
goto out;
bprm.exec = bprm.p;
retval = copy_strings(bprm.envc, envp, &bprm);
bprm->exec = bprm->p;
retval = copy_strings(bprm->envc, envp, bprm);
if (retval < 0)
goto out;
retval = copy_strings(bprm.argc, argv, &bprm);
retval = copy_strings(bprm->argc, argv, bprm);
if (retval < 0)
goto out;
retval = search_binary_handler(&bprm,regs);
retval = search_binary_handler(bprm,regs);
if (retval >= 0) {
free_arg_pages(&bprm);
free_arg_pages(bprm);
/* execve success */
security_bprm_free(&bprm);
security_bprm_free(bprm);
kfree(bprm);
return retval;
}
out:
/* Something went wrong, return the inode and free the argument pages*/
for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
struct page * page = bprm.page[i];
struct page * page = bprm->page[i];
if (page)
__free_page(page);
}
if (bprm.security)
security_bprm_free(&bprm);
if (bprm->security)
security_bprm_free(bprm);
out_mm:
if (bprm.mm)
mmdrop(bprm.mm);
if (bprm->mm)
mmdrop(bprm->mm);
out_file:
if (bprm.file) {
allow_write_access(bprm.file);
fput(bprm.file);
if (bprm->file) {
allow_write_access(bprm->file);
fput(bprm->file);
}
kfree(bprm);
out_ret:
return retval;
}
......
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