untrusted comment: signature from openbsd 5.9 base secret key
RWQJVNompF3pwTjgCAPs773lqZHz26l/fugXC2L0N8EjkzFz4ZoW8xwCV0/2VlAPu28lp+dE7DMQcVJv3Wf6FvYarYgr0FtmUQw=

OpenBSD 5.9 errata 13, Jul 14, 2016:

Splicing sockets in a loop could cause a kernel spin.

Apply by doing:
   signify -Vep /etc/signify/openbsd-59-base.pub -x 013_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_mbuf.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.219.2.1
diff -u -p -r1.219.2.1 uipc_mbuf.c
--- sys/kern/uipc_mbuf.c        28 Apr 2016 22:31:55 -0000      1.219.2.1
+++ sys/kern/uipc_mbuf.c        14 Jul 2016 02:55:23 -0000
@@ -254,6 +254,7 @@ void
m_resethdr(struct mbuf *m)
{
       int len = m->m_pkthdr.len;
+       u_int8_t loopcnt = m->m_pkthdr.ph_loopcnt;

       KASSERT(m->m_flags & M_PKTHDR);
       m->m_flags &= (M_EXT|M_PKTHDR|M_EOR|M_EXTWR|M_ZEROIZE);
@@ -265,6 +266,7 @@ m_resethdr(struct mbuf *m)
       memset(&m->m_pkthdr, 0, sizeof(m->m_pkthdr));
       m->m_pkthdr.pf.prio = IFQ_DEFPRIO;
       m->m_pkthdr.len = len;
+       m->m_pkthdr.ph_loopcnt = loopcnt;
}

struct mbuf *
@@ -1265,7 +1267,8 @@ m_print(void *v,
               (*pr)("m_ptkhdr.ph_tags: %p\tm_pkthdr.ph_tagsset: %b\n",
                   SLIST_FIRST(&m->m_pkthdr.ph_tags),
                   m->m_pkthdr.ph_tagsset, MTAG_BITS);
-               (*pr)("m_pkthdr.ph_flowid: %u\n", m->m_pkthdr.ph_flowid);
+               (*pr)("m_pkthdr.ph_flowid: %u\tm_pkthdr.ph_loopcnt: %u\n",
+                   m->m_pkthdr.ph_flowid, m->m_pkthdr.ph_loopcnt);
               (*pr)("m_pkthdr.csum_flags: %b\n",
                   m->m_pkthdr.csum_flags, MCS_BITS);
               (*pr)("m_pkthdr.ether_vtag: %u\tm_ptkhdr.ph_rtableid: %u\n",
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.149
diff -u -p -r1.149 uipc_socket.c
--- sys/kern/uipc_socket.c      15 Jan 2016 11:58:34 -0000      1.149
+++ sys/kern/uipc_socket.c      14 Jul 2016 02:55:23 -0000
@@ -1199,7 +1199,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;
       }
@@ -1255,6 +1255,15 @@ somove(struct socket *so, int wait)
                       (so->so_proto->pr_usrreq)(so, PRU_RCVD, NULL,
                           (struct mbuf *)0L, NULL, NULL);
               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) {
Index: sys/netinet/tcp_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_output.c,v
retrieving revision 1.116
diff -u -p -r1.116 tcp_output.c
--- sys/netinet/tcp_output.c    5 Dec 2015 10:52:26 -0000       1.116
+++ sys/netinet/tcp_output.c    14 Jul 2016 02:55:23 -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.208
diff -u -p -r1.208 mbuf.h
--- sys/sys/mbuf.h      23 Feb 2016 01:39:14 -0000      1.208
+++ sys/sys/mbuf.h      14 Jul 2016 02:55:23 -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;
};

@@ -485,6 +486,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