Rework the tame cmsg handler to make it work both ways. While on recv one
authorclaudio <claudio@openbsd.org>
Tue, 6 Oct 2015 14:55:41 +0000 (14:55 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 6 Oct 2015 14:55:41 +0000 (14:55 +0000)
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
sys/kern/uipc_syscalls.c
sys/sys/tame.h

index 5d0370d..0c36fb6 100644 (file)
@@ -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. */
index afe5c38..8cb3444 100644 (file)
@@ -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);
index 4f3b82e..c553729 100644 (file)
@@ -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 <nicm@openbsd.org>
@@ -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);