From owner-p4-projects@FreeBSD.ORG Sun Jun 24 08:08:34 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7436116A4ED; Sun, 24 Jun 2007 08:08:34 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 0ABF716A400 for ; Sun, 24 Jun 2007 08:08:34 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id EE0A013C448 for ; Sun, 24 Jun 2007 08:08:33 +0000 (UTC) (envelope-from rdivacky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l5O88Xti085924 for ; Sun, 24 Jun 2007 08:08:33 GMT (envelope-from rdivacky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l5O88XTx085921 for perforce@freebsd.org; Sun, 24 Jun 2007 08:08:33 GMT (envelope-from rdivacky@FreeBSD.org) Date: Sun, 24 Jun 2007 08:08:33 GMT Message-Id: <200706240808.l5O88XTx085921@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to rdivacky@FreeBSD.org using -f From: Roman Divacky To: Perforce Change Reviews Cc: Subject: PERFORCE change 122220 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Jun 2007 08:08:35 -0000 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_