adds fktrace syscall. currently with same behavior (regular files only) as
existing code.
tested with ktrace and...
#include <sys/types.h>
#include <sys/param.h>
#include <sys/uio.h>
#include <sys/ktrace.h>
#include <fcntl.h>
int
main()
{
int fd;
fd = open("ledump", O_CREAT, 0666);
syscall(113, fd, KTROP_SET, KTRFAC_NAMEI, 14750);
}
kdump -f ledump
Index: syscalls.master
===================================================================
RCS file: /cvs/src/sys/kern/syscalls.master,v
retrieving revision 1.176
diff -u -p -r1.176 syscalls.master
--- syscalls.master 28 Apr 2017 13:50:55 -0000 1.176
+++ syscalls.master 11 Aug 2017 21:22:59 -0000
@@ -237,7 +237,12 @@
111 STD { int sys_sigsuspend(int mask); }
112 STD { int sys_sendsyslog(const void *buf, size_t nbyte, \
int flags); }
-113 OBSOL orecvmsg
+#ifdef KTRACE
+113 STD { int sys_fktrace(int fd, int ops, \
+ int facs, pid_t pid); }
+#else
+113 UNIMPL fktrace
+#endif
114 OBSOL osendmsg
115 OBSOL vtrace
116 OBSOL t32_gettimeofday
Index: kern_ktrace.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_ktrace.c,v
retrieving revision 1.91
diff -u -p -r1.91 kern_ktrace.c
--- kern_ktrace.c 14 Feb 2017 10:31:15 -0000 1.91
+++ kern_ktrace.c 11 Aug 2017 21:27:14 -0000
@@ -392,42 +392,28 @@ ktrpledge(struct proc *p, int error, uin
/* Interface and common routines */
-/*
- * ktrace system call
- */
int
-sys_ktrace(struct proc *p, void *v, register_t *retval)
+doktrace(struct vnode *vp, int ops, int facs, pid_t pid, struct proc *p)
{
- struct sys_ktrace_args /* {
- syscallarg(const char *) fname;
- syscallarg(int) ops;
- syscallarg(int) facs;
- syscallarg(pid_t) pid;
- } */ *uap = v;
- struct vnode *vp = NULL;
struct process *pr = NULL;
struct ucred *cred = NULL;
struct pgrp *pg;
- int facs = SCARG(uap, facs) & ~((unsigned) KTRFAC_ROOT);
- int ops = KTROP(SCARG(uap, ops));
- int descend = SCARG(uap, ops) & KTRFLAG_DESCEND;
+ int descend = ops & KTRFLAG_DESCEND;
int ret = 0;
int error = 0;
- struct nameidata nd;
+
+ facs = facs & ~((unsigned)KTRFAC_ROOT);
+ ops = KTROP(ops);
if (ops != KTROP_CLEAR) {
/*
* an operation which requires a file argument.
*/
cred = p->p_ucred;
- NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, fname),
- p);
- nd.ni_pledge = PLEDGE_CPATH | PLEDGE_WPATH;
- if ((error = vn_open(&nd, FWRITE|O_NOFOLLOW, 0)) != 0)
+ if (!vp) {
+ error = EINVAL;
goto done;
- vp = nd.ni_vp;
-
- VOP_UNLOCK(vp, p);
+ }
if (vp->v_type != VREG) {
error = EACCES;
goto done;
@@ -462,11 +448,11 @@ sys_ktrace(struct proc *p, void *v, regi
/*
* do it
*/
- if (SCARG(uap, pid) < 0) {
+ if (pid < 0) {
/*
* by process group
*/
- pg = pgfind(-SCARG(uap, pid));
+ pg = pgfind(-pid);
if (pg == NULL) {
error = ESRCH;
goto done;
@@ -482,7 +468,7 @@ sys_ktrace(struct proc *p, void *v, regi
/*
* by pid
*/
- pr = prfind(SCARG(uap, pid));
+ pr = prfind(pid);
if (pr == NULL) {
error = ESRCH;
goto done;
@@ -495,9 +481,75 @@ sys_ktrace(struct proc *p, void *v, regi
if (!ret)
error = EPERM;
done:
- if (vp != NULL)
- (void) vn_close(vp, FWRITE, cred, p);
return (error);
+}
+
+/*
+ * ktrace system call
+ */
+int
+sys_ktrace(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_ktrace_args /* {
+ syscallarg(const char *) fname;
+ syscallarg(int) ops;
+ syscallarg(int) facs;
+ syscallarg(pid_t) pid;
+ } */ *uap = v;
+ struct vnode *vp = NULL;
+ const char *fname = SCARG(uap, fname);
+ struct ucred *cred = NULL;
+ int error;
+
+ if (fname) {
+ struct nameidata nd;
+
+ cred = p->p_ucred;
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname, p);
+ nd.ni_pledge = PLEDGE_CPATH | PLEDGE_WPATH;
+ if ((error = vn_open(&nd, FWRITE|O_NOFOLLOW, 0)) != 0)
+ return error;
+ vp = nd.ni_vp;
+
+ VOP_UNLOCK(vp, p);
+ }
+
+ error = doktrace(vp, SCARG(uap, ops), SCARG(uap, facs),
+ SCARG(uap, pid), p);
+ if (vp != NULL)
+ (void)vn_close(vp, FWRITE, cred, p);
+
+ return error;
+}
+
+int
+sys_fktrace(struct proc *p, void *v, register_t *retval)
+{
+ struct sys_fktrace_args /* {
+ syscallarg(int) fd;
+ syscallarg(int) ops;
+ syscallarg(int) facs;
+ syscallarg(pid_t) pid;
+ } */ *uap = v;
+ struct vnode *vp = NULL;
+ int fd = SCARG(uap, fd);
+ struct file *fp;
+ int error;
+
+ if (fd != -1) {
+ if ((error = getvnode(p, fd, &fp)) != 0)
+ return error;
+ vp = fp->f_data;
+ vref(vp);
+ FRELE(fp, p);
+ }
+
+ error = doktrace(vp, SCARG(uap, ops), SCARG(uap, facs),
+ SCARG(uap, pid), p);
+ if (vp != NULL)
+ vrele(vp);
+
+ return error;
}
int