summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2015-07-28 05:50:41 +0000
committerguenther <guenther@openbsd.org>2015-07-28 05:50:41 +0000
commit7003901ffaa54cba9c0259fd1e76fbc6abac98f6 (patch)
tree8d848e945d960e39487c1cdafeffd4f576b295c6
parentdefault permitted target is all users, not root. (diff)
downloadwireguard-openbsd-7003901ffaa54cba9c0259fd1e76fbc6abac98f6.tar.xz
wireguard-openbsd-7003901ffaa54cba9c0259fd1e76fbc6abac98f6.zip
Add ktracing of structs iovec, msghdr, and cmsghdr for {,p}{read,write}v(),
sendmsg(), and recvmsg(). For cmsghdr, the len, level, and type are always shown, and for SOL_SOCKET,SCM_RIGHTS the fd numbers being passed are shown. ok millert@ deraadt@
-rw-r--r--sys/kern/sys_generic.c10
-rw-r--r--sys/kern/uipc_syscalls.c26
-rw-r--r--sys/sys/ktrace.h8
-rw-r--r--usr.bin/kdump/ktrstruct.c101
4 files changed, 141 insertions, 4 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index b6752bb5c40..d1c89d52c98 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.99 2015/07/19 02:35:35 deraadt Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.100 2015/07/28 05:50:41 guenther Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -161,6 +161,10 @@ dofilereadv(struct proc *p, int fd, struct file *fp, const struct iovec *iovp,
}
if ((error = copyin(iovp, iov, iovlen)))
goto done;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT))
+ ktriovec(p, iov, iovcnt);
+#endif
} else {
iov = (struct iovec *)iovp; /* de-constify */
}
@@ -309,6 +313,10 @@ dofilewritev(struct proc *p, int fd, struct file *fp, const struct iovec *iovp,
}
if ((error = copyin(iovp, iov, iovlen)))
goto done;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT))
+ ktriovec(p, iov, iovcnt);
+#endif
} else {
iov = (struct iovec *)iovp; /* de-constify */
}
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 74ae41e2910..9b785a06559 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_syscalls.c,v 1.105 2015/07/27 04:01:51 guenther Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.106 2015/07/28 05:50:41 guenther Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
@@ -494,6 +494,10 @@ sys_sendmsg(struct proc *p, void *v, register_t *retval)
error = copyin(SCARG(uap, msg), &msg, sizeof (msg));
if (error)
return (error);
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT))
+ ktrmsghdr(p, &msg);
+#endif
if (tame_sendto_check(p, msg.msg_name))
return (tame_fail(p, EPERM, _TM_UNIX));
@@ -509,6 +513,10 @@ sys_sendmsg(struct proc *p, void *v, register_t *retval)
(error = copyin(msg.msg_iov, iov,
(unsigned)(msg.msg_iovlen * sizeof (struct iovec)))))
goto done;
+#ifdef KTRACE
+ if (msg.msg_iovlen && KTRPOINT(p, KTR_STRUCT))
+ ktriovec(p, iov, msg.msg_iovlen);
+#endif
msg.msg_iov = iov;
msg.msg_flags = 0;
error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
@@ -572,6 +580,11 @@ sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize)
mp->msg_controllen, MT_CONTROL);
if (error)
goto bad;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT) && mp->msg_controllen)
+ ktrcmsghdr(p, mtod(control, char *),
+ mp->msg_controllen);
+#endif
if (tame_cmsg_send(p, control, mp->msg_controllen)) {
m_free(control);
@@ -689,6 +702,13 @@ sys_recvmsg(struct proc *p, void *v, register_t *retval)
msg.msg_iov = iov;
if ((error = recvit(p, SCARG(uap, s), &msg, NULL, retval)) == 0) {
msg.msg_iov = uiov;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT)) {
+ ktrmsghdr(p, &msg);
+ if (msg.msg_iovlen)
+ ktriovec(p, iov, msg.msg_iovlen);
+ }
+#endif
error = copyout(&msg, SCARG(uap, msg), sizeof(msg));
}
done:
@@ -790,6 +810,10 @@ recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp,
struct mbuf *m = control;
caddr_t cp = mp->msg_control;
+#ifdef KTRACE
+ if (KTRPOINT(p, KTR_STRUCT) && len)
+ ktrcmsghdr(p, mtod(control, char *), len);
+#endif
do {
i = m->m_len;
if (len < i) {
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index 846eafd15ca..94fd788e6f7 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ktrace.h,v 1.22 2015/07/19 04:45:25 guenther Exp $ */
+/* $OpenBSD: ktrace.h,v 1.23 2015/07/28 05:50:41 guenther Exp $ */
/* $NetBSD: ktrace.h,v 1.12 1996/02/04 02:12:29 christos Exp $ */
/*
@@ -234,5 +234,11 @@ void ktrstruct(struct proc *, const char *, const void *, size_t);
ktrstruct((p), "fdset", (s), l)
#define ktrquota(p, s) \
ktrstruct((p), "quota", (s), sizeof(struct dqblk))
+#define ktrmsghdr(p, s) \
+ ktrstruct(p, "msghdr", s, sizeof(struct msghdr))
+#define ktriovec(p, s, count) \
+ ktrstruct(p, "iovec", s, (count) * sizeof(struct iovec))
+#define ktrcmsghdr(p, c, len) \
+ ktrstruct(p, "cmsghdr", c, len)
#endif /* !_KERNEL */
diff --git a/usr.bin/kdump/ktrstruct.c b/usr.bin/kdump/ktrstruct.c
index b218ee2027e..2fc328d7c68 100644
--- a/usr.bin/kdump/ktrstruct.c
+++ b/usr.bin/kdump/ktrstruct.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ktrstruct.c,v 1.9 2014/12/16 03:19:23 jsg Exp $ */
+/* $OpenBSD: ktrstruct.c,v 1.10 2015/07/28 05:50:41 guenther Exp $ */
/*-
* Copyright (c) 1988, 1993
@@ -42,6 +42,7 @@
#include <ctype.h>
#include <err.h>
#include <limits.h>
+#include <netdb.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
@@ -364,6 +365,84 @@ ktrquota(const struct dqblk *quota)
printf(" }\n");
}
+static void
+ktrmsghdr(const struct msghdr *msg)
+{
+ printf("struct msghdr { name=%p, namelen=%u, iov=%p, iovlen=%u,"
+ " control=%p, controllen=%u, flags=%d }\n",
+ msg->msg_name, msg->msg_namelen, msg->msg_iov, msg->msg_iovlen,
+ msg->msg_control, msg->msg_controllen, msg->msg_flags);
+}
+
+static void
+ktriovec(const char *data, int count)
+{
+ struct iovec iov;
+ int i;
+
+ printf("struct iovec");
+ if (count > 1)
+ printf(" [%d]", count);
+ for (i = 0; i < count; i++) {
+ memcpy(&iov, data, sizeof(iov));
+ data += sizeof(iov);
+ printf(" { base=%p, len=%lu }", iov.iov_base, iov.iov_len);
+ }
+ printf("\n");
+}
+
+static void
+ktrcmsghdr(char *data, socklen_t len)
+{
+ struct msghdr msg;
+ struct cmsghdr *cmsg;
+ int i, count, *fds;
+
+ msg.msg_control = data;
+ msg.msg_controllen = len;
+
+ /* count the control messages */
+ count = 0;
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ count++;
+ }
+
+ printf("struct cmsghdr");
+ if (count > 1)
+ printf(" [%d]", count);
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ printf(" { len=%u, level=", cmsg->cmsg_len);
+ if (cmsg->cmsg_level == SOL_SOCKET) {
+ printf("SOL_SOCKET, type=");
+ switch (cmsg->cmsg_type) {
+ case SCM_RIGHTS:
+ printf("SCM_RIGHTS, data=");
+ fds = (int *)CMSG_DATA(cmsg);
+ for (i = 0;
+ cmsg->cmsg_len > CMSG_LEN(sizeof(int) * i);
+ i++) {
+ printf("%s%d", i ? "," : "", fds[i]);
+ }
+ break;
+ case SCM_TIMESTAMP:
+ default:
+ printf("%d", cmsg->cmsg_type);
+ break;
+ }
+ } else {
+ struct protoent *p = getprotobynumber(cmsg->cmsg_level);
+
+ printf("%u<%s>, type=%d", cmsg->cmsg_level,
+ p != NULL ? p->p_name : "unknown", cmsg->cmsg_type);
+ }
+ printf(" }");
+ }
+ printf("\n");
+}
+
void
ktrstruct(char *buf, size_t buflen)
{
@@ -449,6 +528,7 @@ ktrstruct(char *buf, size_t buflen)
ktrtfork(&tf);
} else if (strcmp(name, "fdset") == 0) {
struct fd_set *fds;
+
if ((fds = malloc(datalen)) == NULL)
err(1, "malloc");
memcpy(fds, data, datalen);
@@ -461,6 +541,25 @@ ktrstruct(char *buf, size_t buflen)
goto invalid;
memcpy(&quota, data, datalen);
ktrquota(&quota);
+ } else if (strcmp(name, "msghdr") == 0) {
+ struct msghdr msg;
+
+ if (datalen != sizeof(msg))
+ goto invalid;
+ memcpy(&msg, data, datalen);
+ ktrmsghdr(&msg);
+ } else if (strcmp(name, "iovec") == 0) {
+ if (datalen % sizeof(struct iovec))
+ goto invalid;
+ ktriovec(data, datalen / sizeof(struct iovec));
+ } else if (strcmp(name, "cmsghdr") == 0) {
+ char *cmsg;
+
+ if ((cmsg = malloc(datalen)) == NULL)
+ err(1, "malloc");
+ memcpy(cmsg, data, datalen);
+ ktrcmsghdr(cmsg, datalen);
+ free(cmsg);
} else {
printf("unknown structure %s\n", name);
}