Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jun 2007 08:08:33 GMT
From:      Roman Divacky <rdivacky@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 122220 for review
Message-ID:  <200706240808.l5O88XTx085921@repoman.freebsd.org>

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

Change 122220 by rdivacky@rdivacky_witten on 2007/06/24 08:07:41

	Fexecve syscall.
	
	o	modify exec_copyin_args to accept NULL fname argument
	o	introduce fexecve() syscall
	o	modify do_execve to use namei() only when fname != NULL
		and to use binvp instead of ndp->ni_vp
	
	Two problems with this: I am not sure about locking and the fexecve-ed
	process will have "fexec neco" as a process name. The POSIX draft does
	not specify what I should use as the name.

Affected files ...

.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/init_sysent.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_exec.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/syscalls.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/syscalls.master#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/systrace_args.c#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/imgact.h#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscall.h#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscall.mk#4 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/sysproto.h#4 edit

Differences ...

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/init_sysent.c#4 (text+ko) ====

@@ -507,4 +507,5 @@
 	{ AS(faccessat_args), (sy_call_t *)faccessat, AUE_ACCESS, NULL, 0, 0 },	/* 475 = faccessat */
 	{ AS(fchmodat_args), (sy_call_t *)fchmodat, AUE_CHMOD, NULL, 0, 0 },	/* 476 = fchmodat */
 	{ AS(fchownat_args), (sy_call_t *)fchownat, AUE_CHOWN, NULL, 0, 0 },	/* 477 = fchownat */
+	{ AS(fexecve_args), (sy_call_t *)fexecve, AUE_EXECVE, NULL, 0, 0 },	/* 478 = fexecve */
 };

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/kern_exec.c#4 (text+ko) ====

@@ -188,6 +188,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;
@@ -293,7 +314,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;
@@ -354,17 +375,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(td, args->fd, &binvp);
+		if (error)
+			goto exec_fail;
+		VOP_LOCK(binvp, LK_EXCLUSIVE, td);
+		vfslocked = VFS_NEEDSGIANT(binvp->v_mount);
+		imgp->vp = binvp;
+	}
 
 	/*
 	 * Check file permissions (also 'opens' file)
@@ -436,12 +469,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_copy_vnode_label(ndp->ni_vp->v_label, interplabel);
+		mac_copy_vnode_label(binvp->v_label, interplabel);
 #endif
-		vput(ndp->ni_vp);
+		vput(binvp);
 		vm_object_deallocate(imgp->object);
 		imgp->object = NULL;
 		VFS_UNLOCK_GIANT(vfslocked);
@@ -449,6 +483,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;
 	}
 
@@ -494,7 +529,7 @@
 	vn_lock(imgp->vp, LK_EXCLUSIVE | LK_RETRY, td);
 
 	/* 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
@@ -520,8 +555,14 @@
 	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);
+	/* XXX: what for fexecve? */
+	if (args->fname) {
+   		len = min(ndp->ni_cnd.cn_namelen,MAXCOMLEN);
+		bcopy(ndp->ni_cnd.cn_nameptr, p->p_comm, len);
+	} else {
+	   	len = 10;
+	   	bcopy("fexec neco", p->p_comm, 10);
+	}
 	p->p_comm[len] = 0;
 
 	/*
@@ -650,7 +691,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
@@ -733,8 +774,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;
@@ -763,7 +804,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);
 	}
 
@@ -981,11 +1023,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/soc2007/rdivacky/linux_at/sys/kern/syscalls.c#4 (text+ko) ====

@@ -485,4 +485,5 @@
 	"faccessat",			/* 475 = faccessat */
 	"fchmodat",			/* 476 = fchmodat */
 	"fchownat",			/* 477 = fchownat */
+	"fexecve",			/* 478 = fexecve */
 };

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/syscalls.master#4 (text+ko) ====

@@ -838,5 +838,6 @@
 475	AUE_ACCESS	STD	{ int faccessat(int dirfd, char *path, int mode, int flag); }
 476	AUE_CHMOD	STD	{ int fchmodat(int dirfd, char *path, mode_t mode, int flag); }
 477	AUE_CHOWN	STD	{ int fchownat(int dirfd, char *path, uid_t uid, gid_t gid, int flag); }
+478	AUE_EXECVE	STD	{ int fexecve(int fd, char **argv, char **envv); }
 ; Please copy any additions and changes to the following compatability tables:
 ; sys/compat/freebsd32/syscalls.master

==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/systrace_args.c#4 (text+ko) ====

@@ -2836,6 +2836,15 @@
 		*n_args = 5;
 		break;
 	}
+	/* fexecve */
+	case 478: {
+		struct fexecve_args *p = params;
+		iarg[0] = p->fd; /* int */
+		uarg[1] = (intptr_t) p->argv; /* char ** */
+		uarg[2] = (intptr_t) p->envv; /* char ** */
+		*n_args = 3;
+		break;
+	}
 	default:
 		*n_args = 0;
 		break;

==== //depot/projects/soc2007/rdivacky/linux_at/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 {

==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscall.h#4 (text+ko) ====

@@ -397,4 +397,5 @@
 #define	SYS_faccessat	475
 #define	SYS_fchmodat	476
 #define	SYS_fchownat	477
-#define	SYS_MAXSYSCALL	478
+#define	SYS_fexecve	478
+#define	SYS_MAXSYSCALL	479

==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscall.mk#4 (text+ko) ====

@@ -338,4 +338,5 @@
 	sctp_generic_recvmsg.o \
 	faccessat.o \
 	fchmodat.o \
-	fchownat.o
+	fchownat.o \
+	fexecve.o

==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/sysproto.h#4 (text+ko) ====

@@ -1501,6 +1501,11 @@
 	char gid_l_[PADL_(gid_t)]; gid_t gid; char gid_r_[PADR_(gid_t)];
 	char flag_l_[PADL_(int)]; int flag; char flag_r_[PADR_(int)];
 };
+struct fexecve_args {
+	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+	char argv_l_[PADL_(char **)]; char ** argv; char argv_r_[PADR_(char **)];
+	char envv_l_[PADL_(char **)]; char ** envv; char envv_r_[PADR_(char **)];
+};
 int	nosys(struct thread *, struct nosys_args *);
 void	sys_exit(struct thread *, struct sys_exit_args *);
 int	fork(struct thread *, struct fork_args *);
@@ -1836,6 +1841,7 @@
 int	faccessat(struct thread *, struct faccessat_args *);
 int	fchmodat(struct thread *, struct fchmodat_args *);
 int	fchownat(struct thread *, struct fchownat_args *);
+int	fexecve(struct thread *, struct fexecve_args *);
 
 #ifdef COMPAT_43
 
@@ -2390,6 +2396,7 @@
 #define	SYS_AUE_faccessat	AUE_ACCESS
 #define	SYS_AUE_fchmodat	AUE_CHMOD
 #define	SYS_AUE_fchownat	AUE_CHOWN
+#define	SYS_AUE_fexecve	AUE_EXECVE
 
 #undef PAD_
 #undef PADL_



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