Move the common userspace argv and envp counting and stack setup code
into do_execveat_common_bprm(). Keep do_execveat_common() responsible
for the existing RLIMIT_NPROC check, bprm allocation, and error path.
This is a mechanical refactor for later opened-file exec users. It
does not change execve or execveat behavior.

Signed-off-by: Li Chen <[email protected]>
---
 fs/exec.c | 53 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/fs/exec.c b/fs/exec.c
index 2889b7cf808d7..53f7b18d2b1ea 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1775,31 +1775,12 @@ static int bprm_execve(struct linux_binprm *bprm)
        return retval;
 }
 
-static int do_execveat_common(int fd, struct filename *filename,
-                             struct user_arg_ptr argv,
-                             struct user_arg_ptr envp,
-                             int flags)
+static int do_execveat_common_bprm(struct linux_binprm *bprm,
+                                  struct user_arg_ptr argv,
+                                  struct user_arg_ptr envp)
 {
        int retval;
 
-       /*
-        * We move the actual failure in case of RLIMIT_NPROC excess from
-        * set*uid() to execve() because too many poorly written programs
-        * don't check setuid() return code.  Here we additionally recheck
-        * whether NPROC limit is still exceeded.
-        */
-       if ((current->flags & PF_NPROC_EXCEEDED) &&
-           is_rlimit_overlimit(current_ucounts(), UCOUNT_RLIMIT_NPROC, 
rlimit(RLIMIT_NPROC)))
-               return -EAGAIN;
-
-       /* We're below the limit (still or again), so we don't want to make
-        * further execve() calls fail. */
-       current->flags &= ~PF_NPROC_EXCEEDED;
-
-       CLASS(bprm, bprm)(fd, filename, flags);
-       if (IS_ERR(bprm))
-               return PTR_ERR(bprm);
-
        retval = count(argv, MAX_ARG_STRINGS);
        if (retval < 0)
                return retval;
@@ -1846,6 +1827,34 @@ static int do_execveat_common(int fd, struct filename 
*filename,
        return bprm_execve(bprm);
 }
 
+static int do_execveat_common(int fd, struct filename *filename,
+                             struct user_arg_ptr argv,
+                             struct user_arg_ptr envp,
+                             int flags)
+{
+       /*
+        * We move the actual failure in case of RLIMIT_NPROC excess from
+        * set*uid() to execve() because too many poorly written programs
+        * don't check setuid() return code.  Here we additionally recheck
+        * whether NPROC limit is still exceeded.
+        */
+       if ((current->flags & PF_NPROC_EXCEEDED) &&
+           is_rlimit_overlimit(current_ucounts(), UCOUNT_RLIMIT_NPROC, 
rlimit(RLIMIT_NPROC)))
+               return -EAGAIN;
+
+       /*
+        * We're below the limit (still or again), so we don't want to make
+        * further execve() calls fail.
+        */
+       current->flags &= ~PF_NPROC_EXCEEDED;
+
+       CLASS(bprm, bprm)(fd, filename, flags);
+       if (IS_ERR(bprm))
+               return PTR_ERR(bprm);
+
+       return do_execveat_common_bprm(bprm, argv, envp);
+}
+
 int kernel_execve(const char *kernel_filename,
                  const char *const *argv, const char *const *envp)
 {
-- 
2.52.0


Reply via email to