untrusted comment: signature from openbsd 6.2 base secret key RWRVWzAMgtyg7jzKvfbcXaqeYPPxfpMy3RH0sRZCSvMgeLPlqvO4UP3hFnxYwqV3LcZZ4ZB35FHGyswKMW9dMFTaXRvBC5KttAo= OpenBSD 6.2 errata 013, May 8, 2018: Incorrect handling of fragmented IPsec packets could result in a system crash. Apply by doing: signify -Vep /etc/signify/openbsd-62-base.pub -x 013_ipseclen.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/netinet/ip_ah.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ah.c,v retrieving revision 1.131.4.2 diff -u -p -r1.131.4.2 ip_ah.c --- sys/netinet/ip_ah.c 15 Mar 2018 12:34:33 -0000 1.131.4.2 +++ sys/netinet/ip_ah.c 2 May 2018 20:35:18 -0000 @@ -846,10 +846,16 @@ ah_input_cb(struct cryptop *crp) * the mbuf. */ m_adj(m1, rplen + ahx->authsize); - if (!(m1->m_flags & M_PKTHDR)) + /* + * If m1 is the first mbuf, it has set M_PKTHDR and m_adj() + * has already adjusted the packet header length for us. + */ + if (m1 != m) m->m_pkthdr.len -= rplen + ahx->authsize; } else if (roff + rplen + ahx->authsize >= m1->m_len) { + int adjlen; + /* * Part or all of the AH header is at the end * of this mbuf, so first let's remove the @@ -858,16 +864,16 @@ ah_input_cb(struct cryptop *crp) * chain, if any. */ if (roff + rplen + ahx->authsize > m1->m_len) { + adjlen = roff + rplen + ahx->authsize - + m1->m_len; /* Adjust the next mbuf by the remainder. */ - m_adj(m1->m_next, roff + rplen + - ahx->authsize - m1->m_len); + m_adj(m1->m_next, adjlen); /* * The second mbuf is guaranteed not * to have a pkthdr... */ - m->m_pkthdr.len -= - (roff + rplen + ahx->authsize - m1->m_len); + m->m_pkthdr.len -= adjlen; } /* Now, let's unlink the mbuf chain for a second... */ @@ -878,9 +884,14 @@ ah_input_cb(struct cryptop *crp) * ...and trim the end of the first part of * the chain...sick */ - m_adj(m1, -(m1->m_len - roff)); - if (!(m1->m_flags & M_PKTHDR)) - m->m_pkthdr.len -= (m1->m_len - roff); + adjlen = m1->m_len - roff; + m_adj(m1, -adjlen); + /* + * If m1 is the first mbuf, it has set M_PKTHDR and + * m_adj() has already adjusted the packet header len. + */ + if (m1 != m) + m->m_pkthdr.len -= adjlen; /* Finally, let's relink. */ m1->m_next = m0; Index: sys/netinet/ip_esp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_esp.c,v retrieving revision 1.150 diff -u -p -r1.150 ip_esp.c --- sys/netinet/ip_esp.c 11 Aug 2017 21:24:20 -0000 1.150 +++ sys/netinet/ip_esp.c 2 May 2018 20:35:18 -0000 @@ -674,20 +674,28 @@ esp_input_cb(struct cryptop *crp) if (roff == 0) { /* The ESP header was conveniently at the beginning of the mbuf */ m_adj(m1, hlen); - if (!(m1->m_flags & M_PKTHDR)) + /* + * If m1 is the first mbuf, it has set M_PKTHDR and m_adj() + * has already adjusted the packet header length for us. + */ + if (m1 != m) m->m_pkthdr.len -= hlen; } else if (roff + hlen >= m1->m_len) { + int adjlen; + /* * Part or all of the ESP header is at the end of this mbuf, so * first let's remove the remainder of the ESP header from the * beginning of the remainder of the mbuf chain, if any. */ if (roff + hlen > m1->m_len) { + adjlen = roff + hlen - m1->m_len; + /* Adjust the next mbuf by the remainder */ - m_adj(m1->m_next, roff + hlen - m1->m_len); + m_adj(m1->m_next, adjlen); /* The second mbuf is guaranteed not to have a pkthdr */ - m->m_pkthdr.len -= (roff + hlen - m1->m_len); + m->m_pkthdr.len -= adjlen; } /* Now, let's unlink the mbuf chain for a second...*/ @@ -695,9 +703,14 @@ esp_input_cb(struct cryptop *crp) m1->m_next = NULL; /* ...and trim the end of the first part of the chain...sick */ - m_adj(m1, -(m1->m_len - roff)); - if (!(m1->m_flags & M_PKTHDR)) - m->m_pkthdr.len -= (m1->m_len - roff); + adjlen = m1->m_len - roff; + m_adj(m1, -adjlen); + /* + * If m1 is the first mbuf, it has set M_PKTHDR and m_adj() + * has already adjusted the packet header length for us. + */ + if (m1 != m) + m->m_pkthdr.len -= adjlen; /* Finally, let's relink */ m1->m_next = mo; Index: sys/netinet/ip_ipcomp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_ipcomp.c,v retrieving revision 1.57 diff -u -p -r1.57 ip_ipcomp.c --- sys/netinet/ip_ipcomp.c 11 Aug 2017 21:24:20 -0000 1.57 +++ sys/netinet/ip_ipcomp.c 2 May 2018 20:35:18 -0000 @@ -292,27 +292,40 @@ ipcomp_input_cb(struct cryptop *crp) if (roff == 0) { /* The IPCOMP header is at the beginning of m1 */ m_adj(m1, hlen); - if (!(m1->m_flags & M_PKTHDR)) + /* + * If m1 is the first mbuf, it has set M_PKTHDR and m_adj() + * has already adjusted the packet header length for us. + */ + if (m1 != m) m->m_pkthdr.len -= hlen; } else if (roff + hlen >= m1->m_len) { + int adjlen; + if (roff + hlen > m1->m_len) { + adjlen = roff + hlen - m1->m_len; + /* Adjust the next mbuf by the remainder */ - m_adj(m1->m_next, roff + hlen - m1->m_len); + m_adj(m1->m_next, adjlen); /* * The second mbuf is guaranteed not to have a * pkthdr... */ - m->m_pkthdr.len -= (roff + hlen - m1->m_len); + m->m_pkthdr.len -= adjlen; } /* Now, let's unlink the mbuf chain for a second... */ mo = m1->m_next; m1->m_next = NULL; /* ...and trim the end of the first part of the chain...sick */ - m_adj(m1, -(m1->m_len - roff)); - if (!(m1->m_flags & M_PKTHDR)) - m->m_pkthdr.len -= (m1->m_len - roff); + adjlen = m1->m_len - roff; + m_adj(m1, -adjlen); + /* + * If m1 is the first mbuf, it has set M_PKTHDR and m_adj() + * has already adjusted the packet header length for us. + */ + if (m1 != m) + m->m_pkthdr.len -= adjlen; /* Finally, let's relink */ m1->m_next = mo;