From ab5abb255b02bfec9199509f24200ed2c6839155 Mon Sep 17 00:00:00 2001 From: claudio Date: Tue, 6 Oct 2015 14:55:41 +0000 Subject: [PATCH] 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. --- sys/kern/kern_tame.c | 29 ++++++++++------------------- sys/kern/uipc_syscalls.c | 11 +++++++---- sys/sys/tame.h | 7 ++++--- 3 files changed, 21 insertions(+), 26 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 @@ -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); diff --git a/sys/sys/tame.h b/sys/sys/tame.h index 4f3b82edc1a..c553729ce02 100644 --- a/sys/sys/tame.h +++ b/sys/sys/tame.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tame.h,v 1.8 2015/09/30 11:36:07 semarie Exp $ */ +/* $OpenBSD: tame.h,v 1.9 2015/10/06 14:55:41 claudio Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -54,8 +54,9 @@ int tame_fail(struct proc *, int, int); int tame_namei(struct proc *, char *); void tame_aftersyscall(struct proc *, int, int); -int tame_cmsg_send(struct proc *p, void *v, int controllen); -int tame_cmsg_recv(struct proc *p, void *v, int controllen); +struct mbuf; +int tame_cmsg_send(struct proc *p, struct mbuf *control); +int tame_cmsg_recv(struct proc *p, struct mbuf *control); int tame_sysctl_check(struct proc *p, int namelen, int *name, void *new); int tame_adjtime_check(struct proc *p, const void *v); int tame_recvfrom_check(struct proc *p, void *from); -- 2.20.1