Author: kib
Date: Wed Sep 30 02:25:05 2020
New Revision: 366280
URL: https://svnweb.freebsd.org/changeset/base/366280

Log:
  MFC r366085, r366113:
  Do not leak oldvmspace if image activation failed

Modified:
  stable/12/sys/compat/cloudabi/cloudabi_proc.c
  stable/12/sys/compat/freebsd32/freebsd32_misc.c
  stable/12/sys/compat/linux/linux_emul.c
  stable/12/sys/kern/kern_exec.c
  stable/12/sys/sys/imgact.h
  stable/12/sys/sys/syscallsubr.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/compat/cloudabi/cloudabi_proc.c
==============================================================================
--- stable/12/sys/compat/cloudabi/cloudabi_proc.c       Wed Sep 30 02:21:38 
2020        (r366279)
+++ stable/12/sys/compat/cloudabi/cloudabi_proc.c       Wed Sep 30 02:25:05 
2020        (r366280)
@@ -57,7 +57,7 @@ cloudabi_sys_proc_exec(struct thread *td,
            uap->fds, uap->fds_len);
        if (error == 0) {
                args.fd = uap->fd;
-               error = kern_execve(td, &args, NULL);
+               error = kern_execve(td, &args, NULL, oldvmspace);
        }
        post_execve(td, error, oldvmspace);
        return (error);

Modified: stable/12/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/12/sys/compat/freebsd32/freebsd32_misc.c     Wed Sep 30 02:21:38 
2020        (r366279)
+++ stable/12/sys/compat/freebsd32/freebsd32_misc.c     Wed Sep 30 02:25:05 
2020        (r366280)
@@ -438,7 +438,7 @@ freebsd32_execve(struct thread *td, struct freebsd32_e
        error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
            uap->argv, uap->envv);
        if (error == 0)
-               error = kern_execve(td, &eargs, NULL);
+               error = kern_execve(td, &eargs, NULL, oldvmspace);
        post_execve(td, error, oldvmspace);
        return (error);
 }
@@ -457,7 +457,7 @@ freebsd32_fexecve(struct thread *td, struct freebsd32_
            uap->argv, uap->envv);
        if (error == 0) {
                eargs.fd = uap->fd;
-               error = kern_execve(td, &eargs, NULL);
+               error = kern_execve(td, &eargs, NULL, oldvmspace);
        }
        post_execve(td, error, oldvmspace);
        return (error);

Modified: stable/12/sys/compat/linux/linux_emul.c
==============================================================================
--- stable/12/sys/compat/linux/linux_emul.c     Wed Sep 30 02:21:38 2020        
(r366279)
+++ stable/12/sys/compat/linux/linux_emul.c     Wed Sep 30 02:25:05 2020        
(r366280)
@@ -256,7 +256,7 @@ linux_common_execve(struct thread *td, struct image_ar
        if (error != 0)
                return (error);
 
-       error = kern_execve(td, eargs, NULL);
+       error = kern_execve(td, eargs, NULL, oldvmspace);
        post_execve(td, error, oldvmspace);
        if (error != EJUSTRETURN)
                return (error);

Modified: stable/12/sys/kern/kern_exec.c
==============================================================================
--- stable/12/sys/kern/kern_exec.c      Wed Sep 30 02:21:38 2020        
(r366279)
+++ stable/12/sys/kern/kern_exec.c      Wed Sep 30 02:25:05 2020        
(r366280)
@@ -119,7 +119,7 @@ static int sysctl_kern_ps_strings(SYSCTL_HANDLER_ARGS)
 static int sysctl_kern_usrstack(SYSCTL_HANDLER_ARGS);
 static int sysctl_kern_stackprot(SYSCTL_HANDLER_ARGS);
 static int do_execve(struct thread *td, struct image_args *args,
-    struct mac *mac_p);
+    struct mac *mac_p, struct vmspace *oldvmspace);
 
 /* XXX This should be vm_size_t. */
 SYSCTL_PROC(_kern, KERN_PS_STRINGS, ps_strings, CTLTYPE_ULONG|CTLFLAG_RD|
@@ -222,7 +222,7 @@ sys_execve(struct thread *td, struct execve_args *uap)
        error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE,
            uap->argv, uap->envv);
        if (error == 0)
-               error = kern_execve(td, &args, NULL);
+               error = kern_execve(td, &args, NULL, oldvmspace);
        post_execve(td, error, oldvmspace);
        return (error);
 }
@@ -248,7 +248,7 @@ sys_fexecve(struct thread *td, struct fexecve_args *ua
            uap->argv, uap->envv);
        if (error == 0) {
                args.fd = uap->fd;
-               error = kern_execve(td, &args, NULL);
+               error = kern_execve(td, &args, NULL, oldvmspace);
        }
        post_execve(td, error, oldvmspace);
        return (error);
@@ -277,7 +277,7 @@ sys___mac_execve(struct thread *td, struct __mac_execv
        error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE,
            uap->argv, uap->envv);
        if (error == 0)
-               error = kern_execve(td, &args, uap->mac_p);
+               error = kern_execve(td, &args, uap->mac_p, oldvmspace);
        post_execve(td, error, oldvmspace);
        return (error);
 #else
@@ -325,30 +325,26 @@ post_execve(struct thread *td, int error, struct vmspa
                        thread_single_end(p, SINGLE_BOUNDARY);
                PROC_UNLOCK(p);
        }
-       if ((td->td_pflags & TDP_EXECVMSPC) != 0) {
-               KASSERT(p->p_vmspace != oldvmspace,
-                   ("oldvmspace still used"));
-               vmspace_free(oldvmspace);
-               td->td_pflags &= ~TDP_EXECVMSPC;
-       }
+       exec_cleanup(td, oldvmspace);
 }
 
 /*
- * XXX: kern_execve has the astonishing property of not always returning to
+ * kern_execve() has the astonishing property of not always returning to
  * the caller.  If sufficiently bad things happen during the call to
  * do_execve(), it can end up calling exit1(); as a result, callers must
  * avoid doing anything which they might need to undo (e.g., allocating
  * memory).
  */
 int
-kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p)
+kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p,
+    struct vmspace *oldvmspace)
 {
 
        AUDIT_ARG_ARGV(args->begin_argv, args->argc,
            args->begin_envv - args->begin_argv);
        AUDIT_ARG_ENVV(args->begin_envv, args->envc,
            args->endp - args->begin_envv);
-       return (do_execve(td, args, mac_p));
+       return (do_execve(td, args, mac_p, oldvmspace));
 }
 
 /*
@@ -356,7 +352,8 @@ kern_execve(struct thread *td, struct image_args *args
  * userspace pointers from the passed thread.
  */
 static int
-do_execve(struct thread *td, struct image_args *args, struct mac *mac_p)
+do_execve(struct thread *td, struct image_args *args, struct mac *mac_p,
+    struct vmspace *oldvmspace)
 {
        struct proc *p = td->td_proc;
        struct nameidata nd;
@@ -964,6 +961,7 @@ exec_fail:
 
        if (error && imgp->vmspace_destroyed) {
                /* sorry, no more process anymore. exit gracefully */
+               exec_cleanup(td, oldvmspace);
                exit1(td, 0, SIGABRT);
                /* NOT REACHED */
        }
@@ -980,6 +978,17 @@ exec_fail:
         * registers unmodified when returning EJUSTRETURN.
         */
        return (error == 0 ? EJUSTRETURN : error);
+}
+
+void
+exec_cleanup(struct thread *td, struct vmspace *oldvmspace)
+{
+       if ((td->td_pflags & TDP_EXECVMSPC) != 0) {
+               KASSERT(td->td_proc->p_vmspace != oldvmspace,
+                   ("oldvmspace still used"));
+               vmspace_free(oldvmspace);
+               td->td_pflags &= ~TDP_EXECVMSPC;
+       }
 }
 
 int

Modified: stable/12/sys/sys/imgact.h
==============================================================================
--- stable/12/sys/sys/imgact.h  Wed Sep 30 02:21:38 2020        (r366279)
+++ stable/12/sys/sys/imgact.h  Wed Sep 30 02:25:05 2020        (r366280)
@@ -100,6 +100,7 @@ struct vmspace;
 
 int    exec_alloc_args(struct image_args *);
 int    exec_check_permissions(struct image_params *);
+void   exec_cleanup(struct thread *td, struct vmspace *);
 register_t *exec_copyout_strings(struct image_params *);
 void   exec_free_args(struct image_args *);
 int    exec_new_vmspace(struct image_params *, struct sysentvec *);

Modified: stable/12/sys/sys/syscallsubr.h
==============================================================================
--- stable/12/sys/sys/syscallsubr.h     Wed Sep 30 02:21:38 2020        
(r366279)
+++ stable/12/sys/sys/syscallsubr.h     Wed Sep 30 02:25:05 2020        
(r366280)
@@ -63,6 +63,7 @@ struct stat;
 struct thr_param;
 struct uio;
 struct vm_map;
+struct vmspace;
 
 typedef int (*mmap_check_fp_fn)(struct file *, int, int, int);
 
@@ -117,7 +118,7 @@ int kern_cpuset_setid(struct thread *td, cpuwhich_t wh
            id_t id, cpusetid_t setid);
 int    kern_dup(struct thread *td, u_int mode, int flags, int old, int new);
 int    kern_execve(struct thread *td, struct image_args *args,
-           struct mac *mac_p);
+           struct mac *mac_p, struct vmspace *oldvmspace);
 int    kern_fchmodat(struct thread *td, int fd, char *path,
            enum uio_seg pathseg, mode_t mode, int flag);
 int    kern_fchownat(struct thread *td, int fd, char *path,
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to