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

Reply via email to