exec: use bprm from the stack space

struct linux_binprm isn't big and is safe to use from the stack space

Signed-off-by: Park Ju Hyung <qkrwngud825@gmail.com>
[@0ctobot: Adapted for 4.19]
Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
This commit is contained in:
Park Ju Hyung 2020-03-18 19:15:04 +09:00 committed by spakkkk
parent 60b66cad88
commit 518acbdb88

View File

@ -1445,7 +1445,6 @@ static void free_bprm(struct linux_binprm *bprm)
/* If a binfmt changed the interp, free it. */
if (bprm->interp != bprm->filename)
kfree(bprm->interp);
kfree(bprm);
}
int bprm_change_interp(const char *interp, struct linux_binprm *bprm)
@ -1731,7 +1730,7 @@ static int __do_execve_file(int fd, struct filename *filename,
int flags, struct file *file)
{
char *pathbuf = NULL;
struct linux_binprm *bprm;
struct linux_binprm bprm;
struct files_struct *displaced;
int retval;
@ -1758,16 +1757,13 @@ static int __do_execve_file(int fd, struct filename *filename,
if (retval)
goto out_ret;
retval = -ENOMEM;
bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
if (!bprm)
goto out_files;
memset(&bprm, 0, sizeof(bprm));
retval = prepare_bprm_creds(bprm);
retval = prepare_bprm_creds(&bprm);
if (retval)
goto out_free;
check_unsafe_exec(bprm);
check_unsafe_exec(&bprm);
current->in_execve = 1;
if (!file)
@ -1778,11 +1774,11 @@ static int __do_execve_file(int fd, struct filename *filename,
sched_exec();
bprm->file = file;
bprm.file = file;
if (!filename) {
bprm->filename = "none";
bprm.filename = "none";
} else if (fd == AT_FDCWD || filename->name[0] == '/') {
bprm->filename = filename->name;
bprm.filename = filename->name;
} else {
if (filename->name[0] == '\0')
pathbuf = kasprintf(GFP_KERNEL, "/dev/fd/%d", fd);
@ -1799,58 +1795,41 @@ static int __do_execve_file(int fd, struct filename *filename,
* current->files (due to unshare_files above).
*/
if (close_on_exec(fd, rcu_dereference_raw(current->files->fdt)))
bprm->interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
bprm->filename = pathbuf;
bprm.interp_flags |= BINPRM_FLAGS_PATH_INACCESSIBLE;
bprm.filename = pathbuf;
}
bprm->interp = bprm->filename;
bprm.interp = bprm.filename;
retval = bprm_mm_init(bprm);
retval = bprm_mm_init(&bprm);
if (retval)
goto out_unmark;
bprm->argc = count(argv, MAX_ARG_STRINGS);
if (bprm->argc == 0)
pr_warn_once("process '%s' launched '%s' with NULL argv: empty string added\n",
current->comm, bprm->filename);
if ((retval = bprm->argc) < 0)
bprm.argc = count(argv, MAX_ARG_STRINGS);
if ((retval = bprm.argc) < 0)
goto out;
bprm->envc = count(envp, MAX_ARG_STRINGS);
if ((retval = bprm->envc) < 0)
bprm.envc = count(envp, MAX_ARG_STRINGS);
if ((retval = bprm.envc) < 0)
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;
/*
* When argv is empty, add an empty string ("") as argv[0] to
* ensure confused userspace programs that start processing
* from argv[1] won't end up walking envp. See also
* bprm_stack_limits().
*/
if (bprm->argc == 0) {
const char *argv[] = { "", NULL };
retval = copy_strings_kernel(1, argv, bprm);
if (retval < 0)
goto out;
bprm->argc = 1;
}
retval = exec_binprm(bprm);
retval = exec_binprm(&bprm);
if (retval < 0)
goto out;
@ -1870,7 +1849,7 @@ static int __do_execve_file(int fd, struct filename *filename,
rseq_execve(current);
acct_update_integrals(current);
task_numa_free(current, false);
free_bprm(bprm);
free_bprm(&bprm);
kfree(pathbuf);
if (filename)
putname(filename);
@ -1879,9 +1858,9 @@ static int __do_execve_file(int fd, struct filename *filename,
return retval;
out:
if (bprm->mm) {
acct_arg_size(bprm, 0);
mmput(bprm->mm);
if (bprm.mm) {
acct_arg_size(&bprm, 0);
mmput(bprm.mm);
}
out_unmark:
@ -1889,10 +1868,9 @@ out_unmark:
current->in_execve = 0;
out_free:
free_bprm(bprm);
free_bprm(&bprm);
kfree(pathbuf);
out_files:
if (displaced)
reset_files_struct(displaced);
out_ret: