Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 May 2015 07:32:03 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r283359 - in stable/10/sys: amd64/linux32 compat/freebsd32 compat/svr4 i386/ibcs2 i386/linux kern sys
Message-ID:  <201505240732.t4O7W3Xj016178@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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_ */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505240732.t4O7W3Xj016178>