Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 27 Jan 2008 15:45:47 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 134201 for review
Message-ID:  <200801271545.m0RFjlkP000373@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=134201

Change 134201 by rwatson@rwatson_freebsd_capabilities on 2008/01/27 15:45:28

	Import rdivacky's fexecve() code from linux_at branch.  Requires
	some further tweaking to build/work in this branch.
	
	Submitted by:	rdivacky (thanks!)

Affected files ...

.. //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_exec.c#3 edit
.. //depot/projects/trustedbsd/capabilities/src/sys/sys/imgact.h#2 edit

Differences ...

==== //depot/projects/trustedbsd/capabilities/src/sys/kern/kern_exec.c#3 (text+ko) ====

@@ -189,6 +189,27 @@
 }
 
 #ifndef _SYS_SYSPROTO_H_
+struct fexecve_args {
+	int	fd;
+	char	**argv;
+	char	**envv;
+}
+#endif
+int
+fexecve(struct thread *td, struct fexecve_args *uap)
+{
+	int error;
+	struct image_args args;
+
+	error = exec_copyin_args(&args, NULL, UIO_SYSSPACE,
+	    uap->argv, uap->envv);
+	args.fd = uap->fd;
+	if (error == 0)
+		error = kern_execve(td, &args, NULL);
+	return (error);
+}
+
+#ifndef _SYS_SYSPROTO_H_
 struct __mac_execve_args {
 	char	*fname;
 	char	**argv;
@@ -221,27 +242,6 @@
 #endif
 }
 
-#ifndef _SYS_SYSPROTO_H_
-struct fexecve_args {
-	int	fd;
-	char	**argv;
-	char	**envv;
-};
-#endif
-int
-fexecve(td, uap)
-	struct thread *td;
-	struct fexecve_args /* {
-		int	fd;
-		char	**argv;
-		char	**envv;
-	} */ *uap;
-{
-
-	/* XXXRW: Real work to be done here. */
-	return (ENOSYS);
-}
-
 /*
  * XXX: kern_execve has the astonishing property of not always returning to
  * the caller.  If sufficiently bad things happen during the call to
@@ -305,7 +305,7 @@
 	struct ucred *newcred = NULL, *oldcred;
 	struct uidinfo *euip;
 	register_t *stack_base;
-	int error, len, i;
+	int error, len = 0, i;
 	struct image_params image_params, *imgp;
 	struct vattr attr;
 	int (*img_first)(struct image_params *);
@@ -315,7 +315,7 @@
 	struct vnode *tracevp = NULL;
 	struct ucred *tracecred = NULL;
 #endif
-	struct vnode *textvp = NULL;
+	struct vnode *textvp = NULL, *binvp = NULL;
 	int credential_changing;
 	int vfslocked;
 	int textset;
@@ -376,17 +376,29 @@
 	 * XXXAUDIT: It would be desirable to also audit the name of the
 	 * interpreter if this is an interpreted binary.
 	 */
-	ndp = &nd;
-	NDINIT(ndp, LOOKUP, ISOPEN | LOCKLEAF | FOLLOW | SAVENAME | MPSAFE |
-	    AUDITVNODE1, UIO_SYSSPACE, args->fname, td);
+	if (args->fname != NULL) {
+   		ndp = &nd;
+		NDINIT(ndp, LOOKUP, ISOPEN | LOCKLEAF | FOLLOW | SAVENAME 
+		    | MPSAFE | AUDITVNODE1, UIO_SYSSPACE, args->fname, td);
+	}
 
 interpret:
-	error = namei(ndp);
-	if (error)
-		goto exec_fail;
+	if (args->fname != NULL) {
+		error = namei(ndp);
+		if (error)
+			goto exec_fail;
 
-	vfslocked = NDHASGIANT(ndp);
-	imgp->vp = ndp->ni_vp;
+		vfslocked = NDHASGIANT(ndp);
+		binvp  = ndp->ni_vp;
+		imgp->vp = binvp;
+	} else {
+	   	error = fgetvp_exec(td, args->fd, &binvp);
+		if (error)
+			goto exec_fail;
+		vfslocked = VFS_LOCK_GIANT(binvp->v_mount);
+		vn_lock(binvp, LK_EXCLUSIVE | LK_RETRY);
+		imgp->vp = binvp;
+	}
 
 	/*
 	 * Check file permissions (also 'opens' file)
@@ -459,12 +471,13 @@
 		 */
 		imgp->vp->v_vflag &= ~VV_TEXT;
 		/* free name buffer and old vnode */
-		NDFREE(ndp, NDF_ONLY_PNBUF);
+		if (args->fname != NULL)
+   			NDFREE(ndp, NDF_ONLY_PNBUF);
 #ifdef MAC
 		interplabel = mac_vnode_label_alloc();
-		mac_vnode_copy_label(ndp->ni_vp->v_label, interplabel);
+		mac_vnode_copy_label(binvp->v_label, interplabel);
 #endif
-		vput(ndp->ni_vp);
+		vput(binvp);
 		vm_object_deallocate(imgp->object);
 		imgp->object = NULL;
 		VFS_UNLOCK_GIANT(vfslocked);
@@ -472,6 +485,7 @@
 		/* set new name to that of the interpreter */
 		NDINIT(ndp, LOOKUP, LOCKLEAF | FOLLOW | SAVENAME | MPSAFE,
 		    UIO_SYSSPACE, imgp->interpreter_name, td);
+		args->fname = imgp->interpreter_name;
 		goto interpret;
 	}
 
@@ -512,12 +526,12 @@
 	}
 
 	/* close files on exec */
-	VOP_UNLOCK(imgp->vp, 0);
+	VOP_UNLOCK(imgp->vp, 0, td);
 	fdcloseexec(td);
 	vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
 
 	/* Get a reference to the vnode prior to locking the proc */
-	VREF(ndp->ni_vp);
+	VREF(binvp);
 
 	/*
 	 * For security and other reasons, signal handlers cannot
@@ -543,8 +557,26 @@
 	execsigs(p);
 
 	/* name this process - nameiexec(p, ndp) */
-	len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN);
-	bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len);
+	if (args->fname) {
+   		len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN);
+		bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len);
+	} else {
+		char	*freepath;
+		char	*fullpath = NULL;
+
+		error = vn_fullpath(td, binvp, &fullpath, &freepath);
+		if (error == 0) {
+	   		len = min(strlen(fullpath), MAXCOMLEN);
+	   		bcopy(fullpath, p->p_comm, len);
+			if (freepath)
+				free(freepath, M_TEMP);
+		} else {
+			static const char proc_title[] = "fexecved process";
+			len = sizeof(proc_title);
+			bcopy(proc_title, p->p_comm, len);
+		}
+		error = 0;
+	}
 	p->p_comm[len] = 0;
 	bcopy(p->p_comm, td->td_name, sizeof(td->td_name));
 
@@ -612,7 +644,7 @@
 		 */
 		PROC_UNLOCK(p);
 		setugidsafety(td);
-		VOP_UNLOCK(imgp->vp, 0);
+		VOP_UNLOCK(imgp->vp, 0, td);
 		error = fdcheckstd(td);
 		vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY);
 		if (error != 0)
@@ -674,7 +706,7 @@
 	 * to locking the proc lock.
 	 */
 	textvp = p->p_textvp;
-	p->p_textvp = ndp->ni_vp;
+	p->p_textvp = binvp;
 
 	/*
 	 * Notify others that we exec'd, and clear the P_INEXEC flag
@@ -746,7 +778,7 @@
 		crfree(oldcred);
 	else
 		crfree(newcred);
-	VOP_UNLOCK(imgp->vp, 0);
+	VOP_UNLOCK(imgp->vp, 0, td);
 	/*
 	 * Handle deferred decrement of ref counts.
 	 */
@@ -757,8 +789,8 @@
 		vrele(textvp);
 		VFS_UNLOCK_GIANT(tvfslocked);
 	}
-	if (ndp->ni_vp && error != 0)
-		vrele(ndp->ni_vp);
+	if (binvp && error != 0)
+		vrele(binvp);
 #ifdef KTRACE
 	if (tracevp != NULL) {
 		int tvfslocked;
@@ -787,7 +819,8 @@
 		exec_unmap_first_page(imgp);
 
 	if (imgp->vp != NULL) {
-		NDFREE(ndp, NDF_ONLY_PNBUF);
+		if (args->fname)
+   			NDFREE(ndp, NDF_ONLY_PNBUF);
 		vput(imgp->vp);
 	}
 
@@ -1018,11 +1051,14 @@
 	/*
 	 * Copy the file name.
 	 */
-	error = (segflg == UIO_SYSSPACE) ?
-	    copystr(fname, args->fname, PATH_MAX, &length) :
-	    copyinstr(fname, args->fname, PATH_MAX, &length);
-	if (error != 0)
-		goto err_exit;
+	if (fname != NULL) {
+		error = (segflg == UIO_SYSSPACE) ?
+		copystr(fname, args->fname, PATH_MAX, &length) :
+		copyinstr(fname, args->fname, PATH_MAX, &length);
+		if (error != 0)
+			goto err_exit;
+	} else
+		args->fname = NULL;
 
 	/*
 	 * extract arguments first

==== //depot/projects/trustedbsd/capabilities/src/sys/sys/imgact.h#2 (text+ko) ====

@@ -45,6 +45,7 @@
 	int stringspace;	/* space left in arg & env buffer */
 	int argc;		/* count of argument strings */
 	int envc;		/* count of environment strings */
+	int fd;			/* file descriptor of the executable */
 };
 
 struct image_params {



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