[PATCH 1/6] exec: cleanup the execve wrappers
Remove a whole bunch of wrappers that eventually all call __do_execve_file, and consolidate the execvce helpers to: (1) __do_execveat, which is the lowest level helper implementing the actual functionality (2) do_execvat, which is used by all callers that want native pointers (3) do_compat_execve, which is used by all compat syscalls Signed-off-by: Christoph Hellwig --- fs/exec.c | 98 +++-- include/linux/binfmts.h | 12 ++--- init/main.c | 7 +-- kernel/umh.c| 16 +++ 4 files changed, 41 insertions(+), 92 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index e6e8a9a7032784..354fdaa536ae7d 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1815,10 +1815,7 @@ static int exec_binprm(struct linux_binprm *bprm) return 0; } -/* - * sys_execve() executes a new program. - */ -static int __do_execve_file(int fd, struct filename *filename, +static int __do_execveat(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags, struct file *file) @@ -1972,74 +1969,16 @@ static int __do_execve_file(int fd, struct filename *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) -{ - struct user_arg_ptr argv = { .ptr.native = __argv }; - struct user_arg_ptr envp = { .ptr.native = __envp }; - return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); -} - int do_execveat(int fd, struct filename *filename, const char __user *const __user *__argv, const char __user *const __user *__envp, - int flags) + int flags, struct file *file) { struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr envp = { .ptr.native = __envp }; - return do_execveat_common(fd, filename, argv, envp, flags); -} - -#ifdef CONFIG_COMPAT -static int compat_do_execve(struct filename *filename, - const compat_uptr_t __user *__argv, - const compat_uptr_t __user *__envp) -{ - struct user_arg_ptr argv = { - .is_compat = true, - .ptr.compat = __argv, - }; - struct user_arg_ptr envp = { - .is_compat = true, - .ptr.compat = __envp, - }; - return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); -} - -static int compat_do_execveat(int fd, struct filename *filename, - const compat_uptr_t __user *__argv, - const compat_uptr_t __user *__envp, - int flags) -{ - struct user_arg_ptr argv = { - .is_compat = true, - .ptr.compat = __argv, - }; - struct user_arg_ptr envp = { - .is_compat = true, - .ptr.compat = __envp, - }; - return do_execveat_common(fd, filename, argv, envp, flags); + return __do_execveat(fd, filename, argv, envp, flags, file); } -#endif void set_binfmt(struct linux_binfmt *new) { @@ -2070,7 +2009,7 @@ SYSCALL_DEFINE3(execve, const char __user *const __user *, argv, const char __user *const __user *, envp) { - return do_execve(getname(filename), argv, envp); + return do_execveat(AT_FDCWD, getname(filename), argv, envp, 0, NULL); } SYSCALL_DEFINE5(execveat, @@ -2080,18 +2019,34 @@ SYSCALL_DEFINE5(execveat, int, flags) { int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0; + struct filename *name = getname_flags(filename, lookup_flags, NULL); - return do_execveat(fd, - getname_flags(filename, lookup_flags, NULL), - argv, envp, flags); + return do_execveat(fd, name, argv, envp, flags, NULL); } #ifdef CONFIG_COMPAT +static int do_compat_execve(int fd, struct filename *filename, + const compat_uptr_t __user *__argv, + const compat_uptr_t __user *__envp, + int flags) +{ + struct user_arg_ptr argv = { + .is_compat = true, + .ptr.compat = __argv, + }; + struct user_arg_ptr envp = { + .is_compat = true, +
[PATCH 1/6] exec: cleanup the execve wrappers
Remove a whole bunch of wrappers that eventually all call __do_execve_file, and consolidate the execvce helpers to: (1) __do_execveat, which is the lowest level helper implementing the actual functionality (2) do_execvat, which is used by all callers that want native pointers (3) do_compat_execve, which is used by all compat syscalls Signed-off-by: Christoph Hellwig --- fs/exec.c | 98 +++-- include/linux/binfmts.h | 12 ++--- init/main.c | 7 +-- kernel/umh.c| 16 +++ 4 files changed, 41 insertions(+), 92 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index e6e8a9a7032784..354fdaa536ae7d 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1815,10 +1815,7 @@ static int exec_binprm(struct linux_binprm *bprm) return 0; } -/* - * sys_execve() executes a new program. - */ -static int __do_execve_file(int fd, struct filename *filename, +static int __do_execveat(int fd, struct filename *filename, struct user_arg_ptr argv, struct user_arg_ptr envp, int flags, struct file *file) @@ -1972,74 +1969,16 @@ static int __do_execve_file(int fd, struct filename *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) -{ - struct user_arg_ptr argv = { .ptr.native = __argv }; - struct user_arg_ptr envp = { .ptr.native = __envp }; - return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); -} - int do_execveat(int fd, struct filename *filename, const char __user *const __user *__argv, const char __user *const __user *__envp, - int flags) + int flags, struct file *file) { struct user_arg_ptr argv = { .ptr.native = __argv }; struct user_arg_ptr envp = { .ptr.native = __envp }; - return do_execveat_common(fd, filename, argv, envp, flags); -} - -#ifdef CONFIG_COMPAT -static int compat_do_execve(struct filename *filename, - const compat_uptr_t __user *__argv, - const compat_uptr_t __user *__envp) -{ - struct user_arg_ptr argv = { - .is_compat = true, - .ptr.compat = __argv, - }; - struct user_arg_ptr envp = { - .is_compat = true, - .ptr.compat = __envp, - }; - return do_execveat_common(AT_FDCWD, filename, argv, envp, 0); -} - -static int compat_do_execveat(int fd, struct filename *filename, - const compat_uptr_t __user *__argv, - const compat_uptr_t __user *__envp, - int flags) -{ - struct user_arg_ptr argv = { - .is_compat = true, - .ptr.compat = __argv, - }; - struct user_arg_ptr envp = { - .is_compat = true, - .ptr.compat = __envp, - }; - return do_execveat_common(fd, filename, argv, envp, flags); + return __do_execveat(fd, filename, argv, envp, flags, file); } -#endif void set_binfmt(struct linux_binfmt *new) { @@ -2070,7 +2009,7 @@ SYSCALL_DEFINE3(execve, const char __user *const __user *, argv, const char __user *const __user *, envp) { - return do_execve(getname(filename), argv, envp); + return do_execveat(AT_FDCWD, getname(filename), argv, envp, 0, NULL); } SYSCALL_DEFINE5(execveat, @@ -2080,18 +2019,34 @@ SYSCALL_DEFINE5(execveat, int, flags) { int lookup_flags = (flags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0; + struct filename *name = getname_flags(filename, lookup_flags, NULL); - return do_execveat(fd, - getname_flags(filename, lookup_flags, NULL), - argv, envp, flags); + return do_execveat(fd, name, argv, envp, flags, NULL); } #ifdef CONFIG_COMPAT +static int do_compat_execve(int fd, struct filename *filename, + const compat_uptr_t __user *__argv, + const compat_uptr_t __user *__envp, + int flags) +{ + struct user_arg_ptr argv = { + .is_compat = true, + .ptr.compat = __argv, + }; + struct user_arg_ptr envp = { + .is_compat = true, +