Module Name:    src
Committed By:   riz
Date:           Mon Feb 18 22:00:49 UTC 2013

Modified Files:
        src/sys/kern [netbsd-6]: uipc_syscalls.c uipc_usrreq.c

Log Message:
Pull up following revision(s) (requested by riastradh in ticket #831):
        sys/kern/uipc_usrreq.c: revision 1.141
        sys/kern/uipc_syscalls.c: revision 1.159
Fix some screw cases in cmsg file descriptor passing.
- Don't leave garbage in the control buffer if allocating file
descriptors fails in unp_externalize.
- Scrub the space between CMSG_LEN and CMSG_SPACE to avoid kernel
memory disclosure in unp_externalize.
- Don't read past cmsg_len when closing file descriptors that
couldn't get delivered, in free_rights.
ok christos


To generate a diff of this commit:
cvs rdiff -u -r1.154.2.3 -r1.154.2.4 src/sys/kern/uipc_syscalls.c
cvs rdiff -u -r1.136.8.2 -r1.136.8.3 src/sys/kern/uipc_usrreq.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/uipc_syscalls.c
diff -u src/sys/kern/uipc_syscalls.c:1.154.2.3 src/sys/kern/uipc_syscalls.c:1.154.2.4
--- src/sys/kern/uipc_syscalls.c:1.154.2.3	Thu Feb 14 22:13:59 2013
+++ src/sys/kern/uipc_syscalls.c	Mon Feb 18 22:00:49 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_syscalls.c,v 1.154.2.3 2013/02/14 22:13:59 jdc Exp $	*/
+/*	$NetBSD: uipc_syscalls.c,v 1.154.2.4 2013/02/18 22:00:49 riz Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.154.2.3 2013/02/14 22:13:59 jdc Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_syscalls.c,v 1.154.2.4 2013/02/18 22:00:49 riz Exp $");
 
 #include "opt_pipe.h"
 
@@ -742,17 +742,21 @@ sys_recvmsg(struct lwp *l, const struct 
 static void
 free_rights(struct mbuf *m)
 {
-	int nfd;
-	int i;
+	struct cmsghdr *cm;
 	int *fdv;
+	unsigned int nfds, i;
 
-	nfd = m->m_len < CMSG_SPACE(sizeof(int)) ? 0
-	    : (m->m_len - CMSG_SPACE(sizeof(int))) / sizeof(int) + 1;
-	fdv = (int *) CMSG_DATA(mtod(m,struct cmsghdr *));
-	for (i = 0; i < nfd; i++) {
+	KASSERT(sizeof(*cm) <= m->m_len);
+	cm = mtod(m, struct cmsghdr *);
+
+	KASSERT(CMSG_ALIGN(sizeof(*cm)) <= cm->cmsg_len);
+	KASSERT(cm->cmsg_len <= m->m_len);
+	nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) / sizeof(int);
+	fdv = (int *)CMSG_DATA(cm);
+
+	for (i = 0; i < nfds; i++)
 		if (fd_getfile(fdv[i]) != NULL)
 			(void)fd_close(fdv[i]);
-	}
 }
 
 void

Index: src/sys/kern/uipc_usrreq.c
diff -u src/sys/kern/uipc_usrreq.c:1.136.8.2 src/sys/kern/uipc_usrreq.c:1.136.8.3
--- src/sys/kern/uipc_usrreq.c:1.136.8.2	Tue Oct  9 23:45:21 2012
+++ src/sys/kern/uipc_usrreq.c	Mon Feb 18 22:00:49 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_usrreq.c,v 1.136.8.2 2012/10/09 23:45:21 riz Exp $	*/
+/*	$NetBSD: uipc_usrreq.c,v 1.136.8.3 2013/02/18 22:00:49 riz Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.136.8.2 2012/10/09 23:45:21 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.136.8.3 2013/02/18 22:00:49 riz Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1336,14 +1336,24 @@ unp_externalize(struct mbuf *rights, str
 	}
  out:
 	if (__predict_false(error != 0)) {
-		rp = (file_t **)CMSG_DATA(cm);
-		for (size_t i = 0; i < nfds; i++) {
-			file_t * const fp = *rp;
-			*rp++ = 0;
-			unp_discard_now(fp);
-		}
+		file_t **const fpp = (file_t **)CMSG_DATA(cm);
+		for (size_t i = 0; i < nfds; i++)
+			unp_discard_now(fpp[i]);
+		/*
+		 * Truncate the array so that nobody will try to interpret
+		 * what is now garbage in it.
+		 */
+		cm->cmsg_len = CMSG_LEN(0);
+		rights->m_len = CMSG_SPACE(0);
 	}
 
+	/*
+	 * Don't disclose kernel memory in the alignment space.
+	 */
+	KASSERT(cm->cmsg_len <= rights->m_len);
+	memset(&mtod(rights, char *)[cm->cmsg_len], 0, rights->m_len -
+	    cm->cmsg_len);
+
 	rw_exit(&p->p_cwdi->cwdi_lock);
 	kmem_free(fdp, nfds * sizeof(int));
 	return error;

Reply via email to