Author: kib
Date: Sun May 24 07:32:02 2015
New Revision: 283359
URL: https://svnweb.freebsd.org/changeset/base/283359

Log:
  MFC r282708:
  On exec, single-threading must be enforced before arguments space is
  allocated from exec_map.

Modified:
  stable/10/sys/amd64/linux32/linux32_machdep.c
  stable/10/sys/compat/freebsd32/freebsd32_misc.c
  stable/10/sys/compat/svr4/svr4_misc.c
  stable/10/sys/i386/ibcs2/ibcs2_misc.c
  stable/10/sys/i386/linux/linux_machdep.c
  stable/10/sys/kern/kern_exec.c
  stable/10/sys/sys/imgact.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/amd64/linux32/linux32_machdep.c
==============================================================================
--- stable/10/sys/amd64/linux32/linux32_machdep.c       Sun May 24 07:23:16 
2015        (r283358)
+++ stable/10/sys/amd64/linux32/linux32_machdep.c       Sun May 24 07:32:02 
2015        (r283359)
@@ -137,6 +137,7 @@ int
 linux_execve(struct thread *td, struct linux_execve_args *args)
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        char *path;
        int error;
 
@@ -147,12 +148,17 @@ linux_execve(struct thread *td, struct l
                printf(ARGS(execve, "%s"), path);
 #endif
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0) {
+               free(path, M_TEMP);
+               return (error);
+       }
        error = freebsd32_exec_copyin_args(&eargs, path, UIO_SYSSPACE,
            args->argp, args->envp);
        free(path, M_TEMP);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
-       if (error == 0)
+       if (error == 0) {
                /* Linux process can execute FreeBSD one, do not attempt
                 * to create emuldata for such process using
                 * linux_proc_init, this leads to a panic on KASSERT
@@ -160,6 +166,8 @@ linux_execve(struct thread *td, struct l
                 */
                if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX)
                        error = linux_proc_init(td, 0, 0);
+       }
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 

Modified: stable/10/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- stable/10/sys/compat/freebsd32/freebsd32_misc.c     Sun May 24 07:23:16 
2015        (r283358)
+++ stable/10/sys/compat/freebsd32/freebsd32_misc.c     Sun May 24 07:32:02 
2015        (r283359)
@@ -400,12 +400,17 @@ int
 freebsd32_execve(struct thread *td, struct freebsd32_execve_args *uap)
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        int error;
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0)
+               return (error);
        error = freebsd32_exec_copyin_args(&eargs, uap->fname, UIO_USERSPACE,
            uap->argv, uap->envv);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 
@@ -413,14 +418,19 @@ int
 freebsd32_fexecve(struct thread *td, struct freebsd32_fexecve_args *uap)
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        int error;
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0)
+               return (error);
        error = freebsd32_exec_copyin_args(&eargs, NULL, UIO_SYSSPACE,
            uap->argv, uap->envv);
        if (error == 0) {
                eargs.fd = uap->fd;
                error = kern_execve(td, &eargs, NULL);
        }
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 

Modified: stable/10/sys/compat/svr4/svr4_misc.c
==============================================================================
--- stable/10/sys/compat/svr4/svr4_misc.c       Sun May 24 07:23:16 2015        
(r283358)
+++ stable/10/sys/compat/svr4/svr4_misc.c       Sun May 24 07:32:02 2015        
(r283359)
@@ -167,15 +167,22 @@ svr4_sys_execv(td, uap)
        struct svr4_sys_execv_args *uap;
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        char *path;
        int error;
 
        CHECKALTEXIST(td, uap->path, &path);
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0) {
+               free(path, M_TEMP);
+               return (error);
+       }
        error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL);
        free(path, M_TEMP);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 
@@ -185,16 +192,23 @@ svr4_sys_execve(td, uap)
        struct svr4_sys_execve_args *uap;
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        char *path;
        int error;
 
        CHECKALTEXIST(td, uap->path, &path);
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0) {
+               free(path, M_TEMP);
+               return (error);
+       }
        error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp,
            uap->envp);
        free(path, M_TEMP);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 

Modified: stable/10/sys/i386/ibcs2/ibcs2_misc.c
==============================================================================
--- stable/10/sys/i386/ibcs2/ibcs2_misc.c       Sun May 24 07:23:16 2015        
(r283358)
+++ stable/10/sys/i386/ibcs2/ibcs2_misc.c       Sun May 24 07:32:02 2015        
(r283359)
@@ -200,15 +200,22 @@ ibcs2_execv(td, uap)
        struct ibcs2_execv_args *uap;
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        char *path;
        int error;
 
         CHECKALTEXIST(td, uap->path, &path);
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0) {
+               free(path, M_TEMP);
+               return (error);
+       }
        error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp, NULL);
        free(path, M_TEMP);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 
@@ -218,16 +225,23 @@ ibcs2_execve(td, uap) 
         struct ibcs2_execve_args *uap;
 {
        struct image_args eargs;
+       struct vmspace *oldvmspace;
        char *path;
        int error;
 
         CHECKALTEXIST(td, uap->path, &path);
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0) {
+               free(path, M_TEMP);
+               return (error);
+       }
        error = exec_copyin_args(&eargs, path, UIO_SYSSPACE, uap->argp,
            uap->envp);
        free(path, M_TEMP);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 

Modified: stable/10/sys/i386/linux/linux_machdep.c
==============================================================================
--- stable/10/sys/i386/linux/linux_machdep.c    Sun May 24 07:23:16 2015        
(r283358)
+++ stable/10/sys/i386/linux/linux_machdep.c    Sun May 24 07:32:02 2015        
(r283359)
@@ -126,9 +126,10 @@ bsd_to_linux_sigaltstack(int bsa)
 int
 linux_execve(struct thread *td, struct linux_execve_args *args)
 {
-       int error;
-       char *newpath;
        struct image_args eargs;
+       struct vmspace *oldvmspace;
+       char *newpath;
+       int error;
 
        LCONVPATHEXIST(td, args->path, &newpath);
 
@@ -137,12 +138,17 @@ linux_execve(struct thread *td, struct l
                printf(ARGS(execve, "%s"), newpath);
 #endif
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0) {
+               free(newpath, M_TEMP);
+               return (error);
+       }
        error = exec_copyin_args(&eargs, newpath, UIO_SYSSPACE,
            args->argp, args->envp);
        free(newpath, M_TEMP);
        if (error == 0)
                error = kern_execve(td, &eargs, NULL);
-       if (error == 0)
+       if (error == 0) {
                /* linux process can exec fbsd one, dont attempt
                 * to create emuldata for such process using
                 * linux_proc_init, this leads to a panic on KASSERT
@@ -150,6 +156,8 @@ linux_execve(struct thread *td, struct l
                 */
                if (SV_PROC_ABI(td->td_proc) == SV_ABI_LINUX)
                        error = linux_proc_init(td, 0, 0);
+       }
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 

Modified: stable/10/sys/kern/kern_exec.c
==============================================================================
--- stable/10/sys/kern/kern_exec.c      Sun May 24 07:23:16 2015        
(r283358)
+++ stable/10/sys/kern/kern_exec.c      Sun May 24 07:32:02 2015        
(r283359)
@@ -196,21 +196,20 @@ struct execve_args {
 #endif
 
 int
-sys_execve(td, uap)
-       struct thread *td;
-       struct execve_args /* {
-               char *fname;
-               char **argv;
-               char **envv;
-       } */ *uap;
+sys_execve(struct thread *td, struct execve_args *uap)
 {
-       int error;
        struct image_args args;
+       struct vmspace *oldvmspace;
+       int error;
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0)
+               return (error);
        error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE,
            uap->argv, uap->envv);
        if (error == 0)
                error = kern_execve(td, &args, NULL);
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 
@@ -224,15 +223,20 @@ struct fexecve_args {
 int
 sys_fexecve(struct thread *td, struct fexecve_args *uap)
 {
-       int error;
        struct image_args args;
+       struct vmspace *oldvmspace;
+       int error;
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0)
+               return (error);
        error = exec_copyin_args(&args, NULL, UIO_SYSSPACE,
            uap->argv, uap->envv);
        if (error == 0) {
                args.fd = uap->fd;
                error = kern_execve(td, &args, NULL);
        }
+       post_execve(td, error, oldvmspace);
        return (error);
 }
 
@@ -246,65 +250,56 @@ struct __mac_execve_args {
 #endif
 
 int
-sys___mac_execve(td, uap)
-       struct thread *td;
-       struct __mac_execve_args /* {
-               char *fname;
-               char **argv;
-               char **envv;
-               struct mac *mac_p;
-       } */ *uap;
+sys___mac_execve(struct thread *td, struct __mac_execve_args *uap)
 {
 #ifdef MAC
-       int error;
        struct image_args args;
+       struct vmspace *oldvmspace;
+       int error;
 
+       error = pre_execve(td, &oldvmspace);
+       if (error != 0)
+               return (error);
        error = exec_copyin_args(&args, uap->fname, UIO_USERSPACE,
            uap->argv, uap->envv);
        if (error == 0)
                error = kern_execve(td, &args, uap->mac_p);
+       post_execve(td, error, oldvmspace);
        return (error);
 #else
        return (ENOSYS);
 #endif
 }
 
-/*
- * XXX: 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(td, args, mac_p)
-       struct thread *td;
-       struct image_args *args;
-       struct mac *mac_p;
+pre_execve(struct thread *td, struct vmspace **oldvmspace)
 {
-       struct proc *p = td->td_proc;
-       struct vmspace *oldvmspace;
+       struct proc *p;
        int error;
 
-       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);
-       if (p->p_flag & P_HADTHREADS) {
+       KASSERT(td == curthread, ("non-current thread %p", td));
+       error = 0;
+       p = td->td_proc;
+       if ((p->p_flag & P_HADTHREADS) != 0) {
                PROC_LOCK(p);
-               if (thread_single(p, SINGLE_BOUNDARY)) {
-                       PROC_UNLOCK(p);
-                       exec_free_args(args);
-                       return (ERESTART);      /* Try again later. */
-               }
+               if (thread_single(p, SINGLE_BOUNDARY) != 0)
+                       error = ERESTART;
                PROC_UNLOCK(p);
        }
+       KASSERT(error != 0 || (td->td_pflags & TDP_EXECVMSPC) == 0,
+           ("nested execve"));
+       *oldvmspace = p->p_vmspace;
+       return (error);
+}
 
-       KASSERT((td->td_pflags & TDP_EXECVMSPC) == 0, ("nested execve"));
-       oldvmspace = td->td_proc->p_vmspace;
-       error = do_execve(td, args, mac_p);
+void
+post_execve(struct thread *td, int error, struct vmspace *oldvmspace)
+{
+       struct proc *p;
 
-       if (p->p_flag & P_HADTHREADS) {
+       KASSERT(td == curthread, ("non-current thread %p", td));
+       p = td->td_proc;
+       if ((p->p_flag & P_HADTHREADS) != 0) {
                PROC_LOCK(p);
                /*
                 * If success, we upgrade to SINGLE_EXIT state to
@@ -317,13 +312,29 @@ kern_execve(td, args, mac_p)
                PROC_UNLOCK(p);
        }
        if ((td->td_pflags & TDP_EXECVMSPC) != 0) {
-               KASSERT(td->td_proc->p_vmspace != oldvmspace,
+               KASSERT(p->p_vmspace != oldvmspace,
                    ("oldvmspace still used"));
                vmspace_free(oldvmspace);
                td->td_pflags &= ~TDP_EXECVMSPC;
        }
+}
 
-       return (error);
+/*
+ * XXX: 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)
+{
+
+       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));
 }
 
 /*

Modified: stable/10/sys/sys/imgact.h
==============================================================================
--- stable/10/sys/sys/imgact.h  Sun May 24 07:23:16 2015        (r283358)
+++ stable/10/sys/sys/imgact.h  Sun May 24 07:32:02 2015        (r283359)
@@ -86,6 +86,7 @@ struct image_params {
 #ifdef _KERNEL
 struct sysentvec;
 struct thread;
+struct vmspace;
 
 #define IMGACT_CORE_COMPRESS   0x01
 
@@ -98,6 +99,8 @@ void  exec_setregs(struct thread *, struc
 int    exec_shell_imgact(struct image_params *);
 int    exec_copyin_args(struct image_args *, char *, enum uio_seg,
        char **, char **);
+int    pre_execve(struct thread *td, struct vmspace **oldvmspace);
+void   post_execve(struct thread *td, int error, struct vmspace *oldvmspace);
 #endif
 
 #endif /* !_SYS_IMGACT_H_ */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to