untrusted comment: signature from openbsd 5.8 base secret key
RWQNNZXtC/MqP/fPnAU0TuzIso6yhQcaI3iWxDty0b8z2ORBRZtBToXz1po21rG2FFJ7+YlNc4aIAkGyPq0l9S2hwVUFSlOB0QU=

OpenBSD 5.8 errata 18, Jul 14, 2016:

Splicing sockets in a loop could cause a kernel spin.

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

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

Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.141
diff -u -p -r1.141 uipc_socket.c
--- sys/kern/uipc_socket.c	8 Jul 2015 07:21:50 -0000	1.141
+++ sys/kern/uipc_socket.c	14 Jul 2016 03:03:23 -0000
@@ -1195,7 +1195,7 @@ somove(struct socket *so, int wait)
 		goto release;
 	}
 	if (sosp->so_error && sosp->so_error != ETIMEDOUT &&
-	    sosp->so_error != EFBIG) {
+	    sosp->so_error != EFBIG && sosp->so_error != ELOOP) {
 		error = sosp->so_error;
 		goto release;
 	}
@@ -1252,6 +1252,15 @@ somove(struct socket *so, int wait)
 		goto nextpkt;
 	}
 
+	/*
+	 * By splicing sockets connected to localhost, userland might create a
+	 * loop.  Dissolve splicing with error if loop is detected by counter.
+	 */
+	if ((m->m_flags & M_PKTHDR) && m->m_pkthdr.ph_loopcnt++ >= M_MAXLOOP) {
+		error = ELOOP;
+		goto release;
+	}
+
 	if (so->so_proto->pr_flags & PR_ATOMIC) {
 		if ((m->m_flags & M_PKTHDR) == 0)
 			panic("somove pkthdr");
@@ -1324,10 +1333,12 @@ somove(struct socket *so, int wait)
 		goto release;
 	m->m_nextpkt = NULL;
 	if (m->m_flags & M_PKTHDR) {
+		u_int8_t loopcnt = m->m_pkthdr.ph_loopcnt;
 		m_tag_delete_chain(m);
 		memset(&m->m_pkthdr, 0, sizeof(m->m_pkthdr));
 		m->m_pkthdr.len = len;
 		m->m_pkthdr.pf.prio = IFQ_DEFPRIO;
+		m->m_pkthdr.ph_loopcnt = loopcnt;
 	}
 
 	/* Send window update to source peer as receive buffer has changed. */
Index: sys/netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.113
diff -u -p -r1.113 tcp_output.c
--- sys/netinet/tcp_output.c	13 Jul 2015 23:11:37 -0000	1.113
+++ sys/netinet/tcp_output.c	14 Jul 2016 02:56:27 -0000
@@ -732,6 +732,9 @@ send:
 				goto out;
 			}
 		}
+		if (so->so_snd.sb_mb->m_flags & M_PKTHDR)
+			m->m_pkthdr.ph_loopcnt =
+			    so->so_snd.sb_mb->m_pkthdr.ph_loopcnt;
 #endif
 		/*
 		 * If we're sending everything we've got, set PUSH.
Index: sys/sys/mbuf.h
===================================================================
RCS file: /cvs/src/sys/sys/mbuf.h,v
retrieving revision 1.195
diff -u -p -r1.195 mbuf.h
--- sys/sys/mbuf.h	8 Jul 2015 07:21:50 -0000	1.195
+++ sys/sys/mbuf.h	14 Jul 2016 02:56:27 -0000
@@ -130,6 +130,7 @@ struct	pkthdr {
 	u_int16_t		 ether_vtag;	/* Ethernet 802.1p+Q vlan tag */
 	u_int			 ph_rtableid;	/* routing table id */
 	u_int			 ph_ifidx;	/* rcv interface index */
+	u_int8_t		 ph_loopcnt;	/* mbuf is looping in kernel */
 	struct pkthdr_pf	 pf;
 };
 
@@ -464,6 +465,9 @@ struct m_tag *m_tag_next(struct mbuf *, 
  * has payload larger than the value below.
  */
 #define PACKET_TAG_MAXSIZE		52
+
+/* Detect mbufs looping in the kernel when spliced too often. */
+#define M_MAXLOOP	128
 
 /*
  * mbuf lists