On Tue, Jan 24, 2017 at 03:22:13PM +0100, Imre Vad?sz wrote: > This patch fixes two issues in m_split() in sys/kern/uipc_mbuf.c, which > are correctly handled in FreeBSD's m_split():
OK bluhm@ > > If the m_split() would split an mbuf chain exactly between 2 mbufs (i.e. > remain == 0), the returned M_PKTHDR might unnecessarily reference an > mbuf cluster from the first part of the original mbuf chain. So the > returned mbuf would have the M_EXT flag set in n->m_flags, but with > n->m_len == 0. Instead m_split should explicitly handle that case. > > The second issue fixes a case in m_split() where n->m_len isn't initialized > explicitly before returning, and also wasn't pre-zeroed by MGETHDR (since > that calls pool_get without PR_ZERO flag). > > > Index: uipc_mbuf.c > =================================================================== > RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v > retrieving revision 1.239 > diff -u -r1.239 uipc_mbuf.c > --- uipc_mbuf.c 29 Nov 2016 10:22:30 -0000 1.239 > +++ uipc_mbuf.c 24 Jan 2017 14:07:03 -0000 > @@ -1013,6 +1013,12 @@ > n->m_pkthdr.len -= len0; > olen = m0->m_pkthdr.len; > m0->m_pkthdr.len = len0; > + if (remain == 0) { > + n->m_next = m->m_next; > + m->m_next = NULL; > + n->m_len = 0; > + return (n); > + } > if (m->m_flags & M_EXT) > goto extpacket; > if (remain > MHLEN) { > @@ -1023,8 +1029,10 @@ > (void) m_free(n); > m0->m_pkthdr.len = olen; > return (NULL); > - } else > + } else { > + n->m_len = 0; > return (n); > + } > } else > MH_ALIGN(n, remain); > } else if (remain == 0) {