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:
parent
60b66cad88
commit
518acbdb88
74
fs/exec.c
74
fs/exec.c
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user