untrusted comment: verify with openbsd-64-base.pub
RWQq6XmS4eDAcbOws5+4PArtEBik6T7N8BcTk0D/EDxE7HbrMjSEKp35Ah+0yDOfH9lPqS8Ed2cU33jMcBObWVuwwHlccEckGQo=

OpenBSD 6.4 errata 006, November 29, 2018:

UNIX domain sockets leak kernel memory with MSG_PEEK on SCM_RIGHTS, or
can attempt excessive memory allocations leading to crash.

Apply by doing:
    signify -Vep /etc/signify/openbsd-64-base.pub -x 006_uipc.patch.sig \
	-m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.227
diff -u -p -r1.227 uipc_socket.c
--- sys/kern/uipc_socket.c	21 Aug 2018 12:34:11 -0000	1.227
+++ sys/kern/uipc_socket.c	21 Nov 2018 17:59:15 -0000
@@ -661,9 +661,9 @@ soreceive(struct socket *so, struct mbuf
 
 	mp = mp0;
 	if (paddr)
-		*paddr = 0;
+		*paddr = NULL;
 	if (controlp)
-		*controlp = 0;
+		*controlp = NULL;
 	if (flagsp)
 		flags = *flagsp &~ MSG_EOR;
 	else
@@ -810,8 +810,13 @@ dontblock:
 		}
 	}
 	while (m && m->m_type == MT_CONTROL && error == 0) {
+		int skip = 0;
 		if (flags & MSG_PEEK) {
-			if (controlp)
+			if (mtod(m, struct cmsghdr *)->cmsg_type ==
+			    SCM_RIGHTS) {
+				/* don't leak internalized SCM_RIGHTS msgs */
+				skip = 1;
+			} else if (controlp)
 				*controlp = m_copym(m, 0, m->m_len, M_NOWAIT);
 			m = m->m_next;
 		} else {
@@ -822,9 +827,7 @@ dontblock:
 			m = so->so_rcv.sb_mb;
 			sbsync(&so->so_rcv, nextrecord);
 			if (controlp) {
-				if (pr->pr_domain->dom_externalize &&
-				    mtod(cm, struct cmsghdr *)->cmsg_type ==
-				    SCM_RIGHTS) {
+				if (pr->pr_domain->dom_externalize) {
 					error =
 					    (*pr->pr_domain->dom_externalize)
 					    (cm, controllen, flags);
@@ -835,8 +838,7 @@ dontblock:
 				 * Dispose of any SCM_RIGHTS message that went
 				 * through the read path rather than recv.
 				 */
-				if (pr->pr_domain->dom_dispose &&
-				    mtod(cm, struct cmsghdr *)->cmsg_type == SCM_RIGHTS)
+				if (pr->pr_domain->dom_dispose)
 					pr->pr_domain->dom_dispose(cm);
 				m_free(cm);
 			}
@@ -845,7 +847,7 @@ dontblock:
 			nextrecord = so->so_rcv.sb_mb->m_nextpkt;
 		else
 			nextrecord = so->so_rcv.sb_mb;
-		if (controlp) {
+		if (controlp && !skip) {
 			orig_resid = 0;
 			controlp = &(*controlp)->m_next;
 		}
Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.134
diff -u -p -r1.134 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c	9 Jul 2018 10:58:21 -0000	1.134
+++ sys/kern/uipc_usrreq.c	21 Nov 2018 17:59:15 -0000
@@ -663,6 +663,13 @@ unp_externalize(struct mbuf *rights, soc
 	struct file *fp;
 	int nfds, error = 0;
 
+	/*
+	 * This code only works because SCM_RIGHTS is the only supported
+	 * control message type on unix sockets. Enforce this here.
+	 */
+	if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET)
+		return EINVAL;
+
 	nfds = (cm->cmsg_len - CMSG_ALIGN(sizeof(*cm))) /
 	    sizeof(struct fdpass);
 	if (controllen < CMSG_ALIGN(sizeof(struct cmsghdr)))
@@ -800,6 +807,8 @@ unp_internalize(struct mbuf *control, st
 	 * Check for two potential msg_controllen values because
 	 * IETF stuck their nose in a place it does not belong.
 	 */ 
+	if (control->m_len < CMSG_LEN(0) || cm->cmsg_len < CMSG_LEN(0))
+		return (EINVAL);
 	if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
 	    !(cm->cmsg_len == control->m_len ||
 	    control->m_len == CMSG_ALIGN(cm->cmsg_len)))