PERFORCE change 122220 for review
Roman Divacky
rdivacky at FreeBSD.org
Sun Jun 24 08:08:35 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=122220
Change 122220 by rdivacky at 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_
More information about the p4-projects
mailing list