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) {