Skip to content

Commit 25cf336

Browse files
committed
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 <[email protected]> [1] https://lore.kernel.org/linux-fsdevel/[email protected]/ v1: https://lkml.kernel.org/r/[email protected] v2: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Reviewed-by: Greg Kroah-Hartman <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Tested-by: Alexei Starovoitov <[email protected]> Signed-off-by: "Eric W. Biederman" <[email protected]>
1 parent 55e6074 commit 25cf336

File tree

2 files changed

+9
-30
lines changed

2 files changed

+9
-30
lines changed

fs/exec.c

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,13 +1818,14 @@ static int exec_binprm(struct linux_binprm *bprm)
18181818
/*
18191819
* sys_execve() executes a new program.
18201820
*/
1821-
static int __do_execve_file(int fd, struct filename *filename,
1822-
struct user_arg_ptr argv,
1823-
struct user_arg_ptr envp,
1824-
int flags, struct file *file)
1821+
static int do_execveat_common(int fd, struct filename *filename,
1822+
struct user_arg_ptr argv,
1823+
struct user_arg_ptr envp,
1824+
int flags)
18251825
{
18261826
char *pathbuf = NULL;
18271827
struct linux_binprm *bprm;
1828+
struct file *file;
18281829
struct files_struct *displaced;
18291830
int retval;
18301831

@@ -1863,18 +1864,15 @@ static int __do_execve_file(int fd, struct filename *filename,
18631864
check_unsafe_exec(bprm);
18641865
current->in_execve = 1;
18651866

1866-
if (!file)
1867-
file = do_open_execat(fd, filename, flags);
1867+
file = do_open_execat(fd, filename, flags);
18681868
retval = PTR_ERR(file);
18691869
if (IS_ERR(file))
18701870
goto out_unmark;
18711871

18721872
sched_exec();
18731873

18741874
bprm->file = file;
1875-
if (!filename) {
1876-
bprm->filename = "none";
1877-
} else if (fd == AT_FDCWD || filename->name[0] == '/') {
1875+
if (fd == AT_FDCWD || filename->name[0] == '/') {
18781876
bprm->filename = filename->name;
18791877
} else {
18801878
if (filename->name[0] == '\0')
@@ -1935,8 +1933,7 @@ static int __do_execve_file(int fd, struct filename *filename,
19351933
task_numa_free(current, false);
19361934
free_bprm(bprm);
19371935
kfree(pathbuf);
1938-
if (filename)
1939-
putname(filename);
1936+
putname(filename);
19401937
if (displaced)
19411938
put_files_struct(displaced);
19421939
return retval;
@@ -1967,27 +1964,10 @@ static int __do_execve_file(int fd, struct filename *filename,
19671964
if (displaced)
19681965
reset_files_struct(displaced);
19691966
out_ret:
1970-
if (filename)
1971-
putname(filename);
1967+
putname(filename);
19721968
return retval;
19731969
}
19741970

1975-
static int do_execveat_common(int fd, struct filename *filename,
1976-
struct user_arg_ptr argv,
1977-
struct user_arg_ptr envp,
1978-
int flags)
1979-
{
1980-
return __do_execve_file(fd, filename, argv, envp, flags, NULL);
1981-
}
1982-
1983-
int do_execve_file(struct file *file, void *__argv, void *__envp)
1984-
{
1985-
struct user_arg_ptr argv = { .ptr.native = __argv };
1986-
struct user_arg_ptr envp = { .ptr.native = __envp };
1987-
1988-
return __do_execve_file(AT_FDCWD, NULL, argv, envp, 0, file);
1989-
}
1990-
19911971
int do_execve(struct filename *filename,
19921972
const char __user *const __user *__argv,
19931973
const char __user *const __user *__envp)

include/linux/binfmts.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,5 @@ extern int do_execveat(int, struct filename *,
141141
const char __user * const __user *,
142142
const char __user * const __user *,
143143
int);
144-
int do_execve_file(struct file *file, void *__argv, void *__envp);
145144

146145
#endif /* _LINUX_BINFMTS_H */

0 commit comments

Comments
 (0)