mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 22:21:40 +00:00
exec: Remove do_execve_file
Now that the last callser has been removed remove this code from exec. For anyone thinking of resurrecing do_execve_file please note that the code was buggy in several fundamental ways. - It did not ensure the file it was passed was read-only and that deny_write_access had been called on it. Which subtlely breaks invaniants in exec. - The caller of do_execve_file was expected to hold and put a reference to the file, but an extra reference for use by exec was not taken so that when exec put it's reference to the file an underflow occured on the file reference count. - The point of the interface was so that a pathname did not need to exist. Which breaks pathname based LSMs. Tetsuo Handa originally reported these issues[1]. While it was clear that deny_write_access was missing the fundamental incompatibility with the passed in O_RDWR filehandle was not immediately recognized. All of these issues were fixed by modifying the usermode driver code to have a path, so it did not need this hack. Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> [1] https://lore.kernel.org/linux-fsdevel/2a8775b4-1dd5-9d5c-aa42-9872445e0942@i-love.sakura.ne.jp/ v1: https://lkml.kernel.org/r/871rm2f0hi.fsf_-_@x220.int.ebiederm.org v2: https://lkml.kernel.org/r/87lfk54p0m.fsf_-_@x220.int.ebiederm.org Link: https://lkml.kernel.org/r/20200702164140.4468-10-ebiederm@xmission.com Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Acked-by: Alexei Starovoitov <ast@kernel.org> Tested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
parent
55e6074e3f
commit
25cf336de5
38
fs/exec.c
38
fs/exec.c
@ -1818,13 +1818,14 @@ static int exec_binprm(struct linux_binprm *bprm)
|
||||
/*
|
||||
* sys_execve() executes a new program.
|
||||
*/
|
||||
static int __do_execve_file(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags, struct file *file)
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
char *pathbuf = NULL;
|
||||
struct linux_binprm *bprm;
|
||||
struct file *file;
|
||||
struct files_struct *displaced;
|
||||
int retval;
|
||||
|
||||
@ -1863,8 +1864,7 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
check_unsafe_exec(bprm);
|
||||
current->in_execve = 1;
|
||||
|
||||
if (!file)
|
||||
file = do_open_execat(fd, filename, flags);
|
||||
file = do_open_execat(fd, filename, flags);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_unmark;
|
||||
@ -1872,9 +1872,7 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
sched_exec();
|
||||
|
||||
bprm->file = file;
|
||||
if (!filename) {
|
||||
bprm->filename = "none";
|
||||
} else if (fd == AT_FDCWD || filename->name[0] == '/') {
|
||||
if (fd == AT_FDCWD || filename->name[0] == '/') {
|
||||
bprm->filename = filename->name;
|
||||
} else {
|
||||
if (filename->name[0] == '\0')
|
||||
@ -1935,8 +1933,7 @@ static int __do_execve_file(int fd, struct filename *filename,
|
||||
task_numa_free(current, false);
|
||||
free_bprm(bprm);
|
||||
kfree(pathbuf);
|
||||
if (filename)
|
||||
putname(filename);
|
||||
putname(filename);
|
||||
if (displaced)
|
||||
put_files_struct(displaced);
|
||||
return retval;
|
||||
@ -1967,27 +1964,10 @@ out_files:
|
||||
if (displaced)
|
||||
reset_files_struct(displaced);
|
||||
out_ret:
|
||||
if (filename)
|
||||
putname(filename);
|
||||
putname(filename);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int do_execveat_common(int fd, struct filename *filename,
|
||||
struct user_arg_ptr argv,
|
||||
struct user_arg_ptr envp,
|
||||
int flags)
|
||||
{
|
||||
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
|
||||
}
|
||||
|
||||
int do_execve_file(struct file *file, void *__argv, void *__envp)
|
||||
{
|
||||
struct user_arg_ptr argv = { .ptr.native = __argv };
|
||||
struct user_arg_ptr envp = { .ptr.native = __envp };
|
||||
|
||||
return __do_execve_file(AT_FDCWD, NULL, argv, envp, 0, file);
|
||||
}
|
||||
|
||||
int do_execve(struct filename *filename,
|
||||
const char __user *const __user *__argv,
|
||||
const char __user *const __user *__envp)
|
||||
|
@ -141,6 +141,5 @@ extern int do_execveat(int, struct filename *,
|
||||
const char __user * const __user *,
|
||||
const char __user * const __user *,
|
||||
int);
|
||||
int do_execve_file(struct file *file, void *__argv, void *__envp);
|
||||
|
||||
#endif /* _LINUX_BINFMTS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user