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