[PATCH 1/6] exec: cleanup the execve wrappers

2020-06-18 Thread Christoph Hellwig
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

2020-06-15 Thread Christoph Hellwig
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,
+