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>