summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2015-10-06 14:55:42 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2015-10-06 14:55:42 +0000
commit9b7aa79a65523d127329ad649d51ca91a079e143 (patch)
tree714c9e6b77cafd789732a590716d7e01669d8ea8 /sys/kern
parentedb771a835efba720b6c44e799a56910bcd6faef (diff)
Rework the tame cmsg handler to make it work both ways. While on recv one
mbuf blob with all the cmsgs inside while on send cmsgs in an mbuf chain, one mbuf per message. Adjust the calls accordingly. Putting it in so deraadt@ can move forward.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_tame.c29
-rw-r--r--sys/kern/uipc_syscalls.c11
2 files changed, 17 insertions, 23 deletions
diff --git a/sys/kern/kern_tame.c b/sys/kern/kern_tame.c
index 5d0370dad3b..0c36fb6293c 100644
--- a/sys/kern/kern_tame.c
+++ b/sys/kern/kern_tame.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_tame.c,v 1.60 2015/10/06 14:38:23 deraadt Exp $ */
+/* $OpenBSD: kern_tame.c,v 1.61 2015/10/06 14:55:41 claudio Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -679,9 +679,8 @@ tame_aftersyscall(struct proc *p, int code, int error)
* leaving such sockets lying around...
*/
int
-tame_cmsg_recv(struct proc *p, void *v, int controllen)
+tame_cmsg_recv(struct proc *p, struct mbuf *control)
{
- struct mbuf *control = v;
struct msghdr tmp;
struct cmsghdr *cmsg;
int *fdp, fd;
@@ -694,7 +693,7 @@ tame_cmsg_recv(struct proc *p, void *v, int controllen)
/* Scan the cmsg */
memset(&tmp, 0, sizeof(tmp));
tmp.msg_control = mtod(control, struct cmsghdr *);
- tmp.msg_controllen = controllen;
+ tmp.msg_controllen = control->m_len;
cmsg = CMSG_FIRSTHDR(&tmp);
while (cmsg != NULL) {
@@ -743,12 +742,13 @@ tame_cmsg_recv(struct proc *p, void *v, int controllen)
/*
* When tamed, default prevents sending of a cmsg.
+ *
+ * Unlike tame_cmsg_recv tame_cmsg_send is called with individual
+ * cmsgs one per mbuf. So no need to loop or scan.
*/
int
-tame_cmsg_send(struct proc *p, void *v, int controllen)
+tame_cmsg_send(struct proc *p, struct mbuf *control)
{
- struct mbuf *control = v;
- struct msghdr tmp;
struct cmsghdr *cmsg;
int *fdp, fd;
struct file *fp;
@@ -761,20 +761,11 @@ tame_cmsg_send(struct proc *p, void *v, int controllen)
return tame_fail(p, EPERM, TAME_CMSG);
/* Scan the cmsg */
- memset(&tmp, 0, sizeof(tmp));
- tmp.msg_control = mtod(control, struct cmsghdr *);
- tmp.msg_controllen = controllen;
- cmsg = CMSG_FIRSTHDR(&tmp);
-
- while (cmsg != NULL) {
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS)
- break;
- cmsg = CMSG_NXTHDR(&tmp, cmsg);
- }
+ cmsg = mtod(control, struct cmsghdr *);
/* Contains no SCM_RIGHTS, so OK */
- if (cmsg == NULL)
+ if (!(cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS))
return (0);
/* In OpenBSD, a CMSG only contains one SCM_RIGHTS. Check it. */
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index afe5c382e06..8cb3444affd 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_syscalls.c,v 1.110 2015/09/29 16:55:58 deraadt Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.111 2015/10/06 14:55:41 claudio Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
@@ -586,8 +586,9 @@ sendit(struct proc *p, int s, struct msghdr *mp, int flags, register_t *retsize)
mp->msg_controllen);
#endif
- if (tame_cmsg_send(p, control, mp->msg_controllen)) {
+ if (tame_cmsg_send(p, control)) {
m_free(control);
+ error = EPERM;
goto bad;
}
} else
@@ -820,8 +821,10 @@ recvit(struct proc *p, int s, struct msghdr *mp, caddr_t namelenp,
mp->msg_flags |= MSG_CTRUNC;
i = len;
}
-// if (tame_cmsg_recv(p, control, mp->msg_controllen))
-// goto out;
+ if (tame_cmsg_recv(p, m)) {
+ error = EPERM;
+ goto out;
+ }
error = copyout(mtod(m, caddr_t), cp, i);
if (m->m_next)
i = ALIGN(i);