summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Unangst <tedu@cvs.openbsd.org>2017-08-12 00:03:11 +0000
committerTed Unangst <tedu@cvs.openbsd.org>2017-08-12 00:03:11 +0000
commitb0099c648b0920b77d7e8b7718268343ef06def3 (patch)
tree9af83b267d3cf1a426df2d68d097995cd9fa2d61
parent3b5ae02a55575a0c2a8aad8f576f19e1cad88a2c (diff)
add a fktrace syscall that takes a file descriptor instead of a name.
libc and man page parts to come. ok guenther
-rw-r--r--sys/kern/kern_ktrace.c108
-rw-r--r--sys/kern/syscalls.master9
2 files changed, 87 insertions, 30 deletions
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index e1224cebf9f..99bc48feae2 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_ktrace.c,v 1.91 2017/02/14 10:31:15 mpi Exp $ */
+/* $OpenBSD: kern_ktrace.c,v 1.92 2017/08/12 00:03:10 tedu Exp $ */
/* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */
/*
@@ -392,42 +392,28 @@ ktrpledge(struct proc *p, int error, uint64_t code, int syscall)
/* 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, register_t *retval)
/*
* 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, register_t *retval)
/*
* by pid
*/
- pr = prfind(SCARG(uap, pid));
+ pr = prfind(pid);
if (pr == NULL) {
error = ESRCH;
goto done;
@@ -495,11 +481,77 @@ sys_ktrace(struct proc *p, void *v, register_t *retval)
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
ktrops(struct proc *curp, struct process *pr, int ops, int facs,
struct vnode *vp, struct ucred *cred)
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 15cf55de433..d3ef28a84a9 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -1,4 +1,4 @@
-; $OpenBSD: syscalls.master,v 1.176 2017/04/28 13:50:55 mpi Exp $
+; $OpenBSD: syscalls.master,v 1.177 2017/08/12 00:03:10 tedu Exp $
; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -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