From nobody@FreeBSD.org  Thu Feb 14 12:58:41 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	by hub.freebsd.org (Postfix) with ESMTP id 31FB29C
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Feb 2013 12:58:41 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 21A96FD9
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Feb 2013 12:58:41 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id r1ECwdZD084020
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Feb 2013 12:58:39 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id r1ECwdA5084019;
	Thu, 14 Feb 2013 12:58:39 GMT
	(envelope-from nobody)
Message-Id: <201302141258.r1ECwdA5084019@red.freebsd.org>
Date: Thu, 14 Feb 2013 12:58:39 GMT
From: Jacques Fourie <jacques.fourie@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Bug in m_split() when splitting M_EXT mbufs
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         176144
>Category:       kern
>Synopsis:       [kernel] [patch] Bug in m_split() when splitting M_EXT mbufs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    glebius
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 14 13:00:00 UTC 2013
>Closed-Date:    Wed Jan 22 09:26:52 UTC 2014
>Last-Modified:  Wed Jan 22 09:26:52 UTC 2014
>Originator:     Jacques Fourie
>Release:        10-current
>Organization:
Netronome Systems
>Environment:
FreeBSD fbsd10vm 10.0-CURRENT FreeBSD 10.0-CURRENT #7 r+45b4c99-dirty: Mon Jan  7 09:40:08 SAST 2013     root@fbsd10vm:/usr/obj/usr/home/jfourie/freebsd.git/sys/FBSD10VM  amd64
>Description:
The following text is copied from my original mail to -hackers:

Could someone please verify if m_split as in svn rev 245286 is doing the
right thing in the scenario where a mbuf chain is split with len0 falling
on a mbuf boundary and the mbuf in question being a M_EXT mbuf? Consider
the following example where m0 is a mbuf chain consisting of 2 M_EXT mbufs,
both 1448 bytes in length. Let len0 be 1448. The 'len0 > m->m_len' check
will be false so the for loop will not be entered in this case. We now have
len = 1448 and remain = 0 and m still points to the first mbuf in the
chain. Also assume that m0 is a pkthdr mbuf. A new pkthdr mbuf n will be
allocated and initialized before the following piece of code is executed :

extpacket:
         if (m->m_flags & M_EXT) {
                n->m_data = m->m_data + len;
                mb_dupcl(n, m);
         } else {
                bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
         } 
         n->m_len = remain;
         m->m_len = len;
         n->m_next = m->m_next;
         m->m_next = NULL;

As m is a M_EXT mbuf the code in the if() clause will be executed. The
problem is that m still points to the first mbuf so effectively the data
pointer for n is assigned to the end of m's data pointer. It should
actually point to the start of the data pointer of the next mbuf in the
original m0 chain, right?
>How-To-Repeat:

>Fix:
Attached patch fixes the issue for me

Patch attached with submission follows:

diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c
index ab6163d..5c397fa 100644
--- a/sys/kern/uipc_mbuf.c
+++ b/sys/kern/uipc_mbuf.c
@@ -1132,6 +1132,23 @@ m_split(struct mbuf *m0, int len0, int wait)
 		return (NULL);
 	remain = m->m_len - len;
 	if (m0->m_flags & M_PKTHDR) {
+		if (remain == 0) {
+			if (m->m_next == NULL)
+				return (NULL);
+			if (!(m->m_next->m_flags & M_PKTHDR)) {
+				MGETHDR(n, wait, m0->m_type);
+				if (n == NULL)
+					return (NULL);
+				MH_ALIGN(n, 0);
+				n->m_next = m->m_next;
+			} else 
+				n = m->m_next;
+			m->m_next = NULL;
+			n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
+			n->m_pkthdr.len = m0->m_pkthdr.len - len0;
+			m0->m_pkthdr.len = len0;
+			return (n);
+		}
 		MGETHDR(n, wait, m0->m_type);
 		if (n == NULL)
 			return (NULL);


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->glebius 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Thu Feb 14 13:03:20 UTC 2013 
Responsible-Changed-Why:  
I promised to look at this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176144 

From: Gleb Smirnoff <glebius@freebsd.org>
To: Jacques Fourie <jacques.fourie@gmail.com>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 15:37:57 +0400

 --nYySOmuH/HDX6pKp
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: inline
 
   Hi, Jacques!
 
   Sorry for delay. Back to m_split():
 
   You are right, it is better to handle this case separately, rather
 than try to catch it in common code. We actually already got a special
 case for (remain == 0) and non-pkthdr mbuf, so adding one for pkthdr
 would be nice.
 
   I have reformatted a bit your patch.
 
   I have also removed the MH_ALIGN(, 0) macro. I don't see any point in
 shifting the data pointer in the mbuf to its end value. The newly allocated
 mbuf has m_len set to zero, so it already is marked as containing no data.
 
   Can you please review and test? Or you can forward your test case to me.
 
   Patch again head, won't apply to stable/9, but difference is obvious.
 
 -- 
 Totus tuus, Glebius.
 
 --nYySOmuH/HDX6pKp
 Content-Type: text/x-diff; charset=koi8-r
 Content-Disposition: attachment; filename="kern.176144.diff"
 
 Index: kern/uipc_mbuf.c
 ===================================================================
 --- kern/uipc_mbuf.c	(revision 248699)
 +++ kern/uipc_mbuf.c	(working copy)
 @@ -1197,8 +1197,17 @@ m_split(struct mbuf *m0, int len0, int wait)
  	if (m == NULL)
  		return (NULL);
  	remain = m->m_len - len;
 -	if (m0->m_flags & M_PKTHDR) {
 +	if (m0->m_flags & M_PKTHDR && remain == 0) {
  		n = m_gethdr(wait, m0->m_type);
 +			return (NULL);
 +		n->m_next = m->m_next;
 +		m->m_next = NULL;
 +		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
 +		n->m_pkthdr.len = m0->m_pkthdr.len - len0;
 +		m0->m_pkthdr.len = len0;
 +		return (n);
 +	} else if (m0->m_flags & M_PKTHDR) {
 +		n = m_gethdr(wait, m0->m_type);
  		if (n == NULL)
  			return (NULL);
  		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
 
 --nYySOmuH/HDX6pKp--

From: Jacques Fourie <jacques.fourie@gmail.com>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 14:21:10 +0200

 --047d7bb04c9019d5bc04d8bed706
 Content-Type: multipart/alternative; boundary=047d7bb04c9019d5b504d8bed704
 
 --047d7bb04c9019d5b504d8bed704
 Content-Type: text/plain; charset=ISO-8859-1
 
 Hi Gleb,
 
 On Mon, Mar 25, 2013 at 1:37 PM, Gleb Smirnoff <glebius@freebsd.org> wrote:
 
 >   Hi, Jacques!
 >
 >   Sorry for delay. Back to m_split():
 >
 >   You are right, it is better to handle this case separately, rather
 > than try to catch it in common code. We actually already got a special
 > case for (remain == 0) and non-pkthdr mbuf, so adding one for pkthdr
 > would be nice.
 >
 >   I have reformatted a bit your patch.
 >
 >   I have also removed the MH_ALIGN(, 0) macro. I don't see any point in
 > shifting the data pointer in the mbuf to its end value. The newly allocated
 > mbuf has m_len set to zero, so it already is marked as containing no data.
 >
 >   Can you please review and test? Or you can forward your test case to me.
 >
 >   Patch again head, won't apply to stable/9, but difference is obvious
 
 
 > --
 > Totus tuus, Glebius.
 >
 The attached diff doesn't apply cleanly for me against r248699. I've
 attached a version of the patch that does apply cleanly - is this what you
 intended? Your patch also always allocates a new pkthdr mbuf to prepend to
 the returned tail even if the next mbuf is a PKTHDR mbuf. While this would
 probably not cause any issues it is probably better to skip the extra mbuf
 allocation?
 
 --047d7bb04c9019d5b504d8bed704
 Content-Type: text/html; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 <div dir=3D"ltr">Hi Gleb,<div><br></div><div class=3D"gmail_extra"><div cla=
 ss=3D"gmail_quote">On Mon, Mar 25, 2013 at 1:37 PM, Gleb Smirnoff <span dir=
 =3D"ltr">&lt;<a href=3D"mailto:glebius@freebsd.org" target=3D"_blank">glebi=
 us@freebsd.org</a>&gt;</span> wrote:<br>
 <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
 left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
 adding-left:1ex">=A0 Hi, Jacques!<br>
 <br>
 =A0 Sorry for delay. Back to m_split():<br>
 <br>
 =A0 You are right, it is better to handle this case separately, rather<br>
 than try to catch it in common code. We actually already got a special<br>
 case for (remain =3D=3D 0) and non-pkthdr mbuf, so adding one for pkthdr<br=
 >
 would be nice.<br>
 <br>
 =A0 I have reformatted a bit your patch.<br>
 <br>
 =A0 I have also removed the MH_ALIGN(, 0) macro. I don&#39;t see any point =
 in<br>
 shifting the data pointer in the mbuf to its end value. The newly allocated=
 <br>
 mbuf has m_len set to zero, so it already is marked as containing no data.<=
 br>
 <br>
 =A0 Can you please review and test? Or you can forward your test case to me=
 .<br>
 <br>
 =A0 Patch again head, won&#39;t apply to stable/9, but difference is obviou=
 s</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
  0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
 -style:solid;padding-left:1ex">
 <br></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
 eft-style:solid;padding-left:1ex"><span class=3D""><font color=3D"#888888">
 --<br>
 Totus tuus, Glebius.<br>
 </font></span></blockquote></div><div>The attached diff doesn&#39;t apply c=
 leanly for me against r248699. I&#39;ve attached a version of the patch tha=
 t does apply cleanly - is this what you intended? Your patch also always al=
 locates a new pkthdr mbuf to prepend to the returned tail even if the next =
 mbuf is a PKTHDR mbuf. While this would probably not cause any issues it is=
  probably better to skip the extra mbuf allocation?</div>
 <div><br></div></div></div>
 
 --047d7bb04c9019d5b504d8bed704--
 --047d7bb04c9019d5bc04d8bed706
 Content-Type: application/octet-stream; name="kern.176144.diff"
 Content-Disposition: attachment; filename="kern.176144.diff"
 Content-Transfer-Encoding: base64
 X-Attachment-Id: f_hepltpp31
 
 ZGlmZiAtLWdpdCBhL3N5cy9rZXJuL3VpcGNfbWJ1Zi5jIGIvc3lzL2tlcm4vdWlwY19tYnVmLmMK
 aW5kZXggZWE0ZmQ4MC4uMjZiZTk5MyAxMDA2NDQKLS0tIGEvc3lzL2tlcm4vdWlwY19tYnVmLmMK
 KysrIGIvc3lzL2tlcm4vdWlwY19tYnVmLmMKQEAgLTExOTcsNyArMTE5NywxNyBAQCBtX3NwbGl0
 KHN0cnVjdCBtYnVmICptMCwgaW50IGxlbjAsIGludCB3YWl0KQogICAgICAgIGlmIChtID09IE5V
 TEwpCiAgICAgICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIHJlbWFpbiA9IG0tPm1f
 bGVuIC0gbGVuOwotICAgICAgIGlmIChtMC0+bV9mbGFncyAmIE1fUEtUSERSKSB7CisgICAgICAg
 aWYgKG0wLT5tX2ZsYWdzICYgTV9QS1RIRFIgJiYgcmVtYWluID09IDApIHsKKyAgICAgICAgICAg
 ICAgIG4gPSBtX2dldGhkcih3YWl0LCBtMC0+bV90eXBlKTsKKyAgICAgICAgICAgICAgIGlmIChu
 ID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CisgICAgICAg
 ICAgICAgICBuLT5tX25leHQgPSBtLT5tX25leHQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAg
 CisgICAgICAgICAgICAgICBtLT5tX25leHQgPSBOVUxMOyAgICAgICAgICAgICAgICAgICAgICAg
 ICAgICAgICAgCisgICAgICAgICAgICAgICBuLT5tX3BrdGhkci5yY3ZpZiA9IG0wLT5tX3BrdGhk
 ci5yY3ZpZjsgICAgICAgICAgCisgICAgICAgICAgICAgICBuLT5tX3BrdGhkci5sZW4gPSBtMC0+
 bV9wa3RoZHIubGVuIC0gbGVuMDsgICAgICAgCisgICAgICAgICAgICAgICBtMC0+bV9wa3RoZHIu
 bGVuID0gbGVuMDsgCisgICAgICAgICAgICAgICByZXR1cm4gKG4pOyAgICAgCisgICAgICAgfSBl
 bHNlIGlmIChtMC0+bV9mbGFncyAmIE1fUEtUSERSKSB7CiAgICAgICAgICAgICAgICBuID0gbV9n
 ZXRoZHIod2FpdCwgbTAtPm1fdHlwZSk7CiAgICAgICAgICAgICAgICBpZiAobiA9PSBOVUxMKQog
 ICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKE5VTEwpOwo=
 --047d7bb04c9019d5bc04d8bed706--

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Jacques Fourie <jacques.fourie@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 16:24:41 +0400

 On Mon, Mar 25, 2013 at 02:21:10PM +0200, Jacques Fourie wrote:
 J> >   Sorry for delay. Back to m_split():
 J> >
 J> >   You are right, it is better to handle this case separately, rather
 J> > than try to catch it in common code. We actually already got a special
 J> > case for (remain == 0) and non-pkthdr mbuf, so adding one for pkthdr
 J> > would be nice.
 J> >
 J> >   I have reformatted a bit your patch.
 J> >
 J> >   I have also removed the MH_ALIGN(, 0) macro. I don't see any point in
 J> > shifting the data pointer in the mbuf to its end value. The newly allocated
 J> > mbuf has m_len set to zero, so it already is marked as containing no data.
 J> >
 J> >   Can you please review and test? Or you can forward your test case to me.
 J> >
 J> >   Patch again head, won't apply to stable/9, but difference is obvious
 J> 
 J> The attached diff doesn't apply cleanly for me against r248699. I've
 J> attached a version of the patch that does apply cleanly - is this what you
 J> intended? Your patch also always allocates a new pkthdr mbuf to prepend to
 J> the returned tail even if the next mbuf is a PKTHDR mbuf. While this would
 J> probably not cause any issues it is probably better to skip the extra mbuf
 J> allocation?
 
 Right, I forgot to mention that in my email. In the networking stack it must
 not happen that a non-first mbuf in chain is pkthdr mbuf.
 
 -- 
 Totus tuus, Glebius.

From: Jacques Fourie <jacques.fourie@gmail.com>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 14:34:20 +0200

 --f46d044287f22a922604d8bf06b2
 Content-Type: text/plain; charset=ISO-8859-1
 
 On Mon, Mar 25, 2013 at 2:24 PM, Gleb Smirnoff <glebius@freebsd.org> wrote:
 
 > On Mon, Mar 25, 2013 at 02:21:10PM +0200, Jacques Fourie wrote:
 > J> >   Sorry for delay. Back to m_split():
 > J> >
 > J> >   You are right, it is better to handle this case separately, rather
 > J> > than try to catch it in common code. We actually already got a special
 > J> > case for (remain == 0) and non-pkthdr mbuf, so adding one for pkthdr
 > J> > would be nice.
 > J> >
 > J> >   I have reformatted a bit your patch.
 > J> >
 > J> >   I have also removed the MH_ALIGN(, 0) macro. I don't see any point
 > in
 > J> > shifting the data pointer in the mbuf to its end value. The newly
 > allocated
 > J> > mbuf has m_len set to zero, so it already is marked as containing no
 > data.
 > J> >
 > J> >   Can you please review and test? Or you can forward your test case
 > to me.
 > J> >
 > J> >   Patch again head, won't apply to stable/9, but difference is obvious
 > J>
 > J> The attached diff doesn't apply cleanly for me against r248699. I've
 > J> attached a version of the patch that does apply cleanly - is this what
 > you
 > J> intended? Your patch also always allocates a new pkthdr mbuf to prepend
 > to
 > J> the returned tail even if the next mbuf is a PKTHDR mbuf. While this
 > would
 > J> probably not cause any issues it is probably better to skip the extra
 > mbuf
 > J> allocation?
 >
 > Right, I forgot to mention that in my email. In the networking stack it
 > must
 > not happen that a non-first mbuf in chain is pkthdr mbuf.
 >
 > --
 > Totus tuus, Glebius.
 >
 In my use case I call m_split() to split a chain of mbufs returned by
 soreceive(). If I understand correctly the socket receive buffer may
 contain a chain of mbufs with a PKTHDR mbuf as the non-first mbuf? If
 m_split() is not intended for this use case I am happy to continue using a
 custom version, only asking for my own understanding.
 
 Regards,
 Jacques
 
 --f46d044287f22a922604d8bf06b2
 Content-Type: text/html; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 <div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
 _quote">On Mon, Mar 25, 2013 at 2:24 PM, Gleb Smirnoff <span dir=3D"ltr">&l=
 t;<a href=3D"mailto:glebius@freebsd.org" target=3D"_blank">glebius@freebsd.=
 org</a>&gt;</span> wrote:<br>
 <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
 x #ccc solid;padding-left:1ex">On Mon, Mar 25, 2013 at 02:21:10PM +0200, Ja=
 cques Fourie wrote:<br>
 J&gt; &gt; =A0 Sorry for delay. Back to m_split():<br>
 J&gt; &gt;<br>
 J&gt; &gt; =A0 You are right, it is better to handle this case separately, =
 rather<br>
 J&gt; &gt; than try to catch it in common code. We actually already got a s=
 pecial<br>
 J&gt; &gt; case for (remain =3D=3D 0) and non-pkthdr mbuf, so adding one fo=
 r pkthdr<br>
 J&gt; &gt; would be nice.<br>
 J&gt; &gt;<br>
 J&gt; &gt; =A0 I have reformatted a bit your patch.<br>
 J&gt; &gt;<br>
 J&gt; &gt; =A0 I have also removed the MH_ALIGN(, 0) macro. I don&#39;t see=
  any point in<br>
 J&gt; &gt; shifting the data pointer in the mbuf to its end value. The newl=
 y allocated<br>
 J&gt; &gt; mbuf has m_len set to zero, so it already is marked as containin=
 g no data.<br>
 J&gt; &gt;<br>
 J&gt; &gt; =A0 Can you please review and test? Or you can forward your test=
  case to me.<br>
 J&gt; &gt;<br>
 J&gt; &gt; =A0 Patch again head, won&#39;t apply to stable/9, but differenc=
 e is obvious<br>
 J&gt;<br>
 J&gt; The attached diff doesn&#39;t apply cleanly for me against r248699. I=
 &#39;ve<br>
 J&gt; attached a version of the patch that does apply cleanly - is this wha=
 t you<br>
 J&gt; intended? Your patch also always allocates a new pkthdr mbuf to prepe=
 nd to<br>
 J&gt; the returned tail even if the next mbuf is a PKTHDR mbuf. While this =
 would<br>
 J&gt; probably not cause any issues it is probably better to skip the extra=
  mbuf<br>
 J&gt; allocation?<br>
 <br>
 Right, I forgot to mention that in my email. In the networking stack it mus=
 t<br>
 not happen that a non-first mbuf in chain is pkthdr mbuf.<br>
 <span class=3D"HOEnZb"><font color=3D"#888888"><br>
 --<br>
 Totus tuus, Glebius.<br></font></span></blockquote><div style>In my use cas=
 e I call m_split() to split a chain of mbufs returned by soreceive(). If I =
 understand correctly the socket receive buffer may contain a chain of mbufs=
  with a PKTHDR mbuf as the non-first mbuf? If m_split() is not intended for=
  this use case I am happy to continue using a custom version, only asking f=
 or my own understanding.</div>
 <div style><br></div><div style>Regards,</div><div style>Jacques=A0</div></=
 div><br></div></div>
 
 --f46d044287f22a922604d8bf06b2--

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Jacques Fourie <jacques.fourie@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 16:46:39 +0400

 On Mon, Mar 25, 2013 at 02:34:20PM +0200, Jacques Fourie wrote:
 J> > Right, I forgot to mention that in my email. In the networking stack it
 J> > must
 J> > not happen that a non-first mbuf in chain is pkthdr mbuf.
 J> >
 J> In my use case I call m_split() to split a chain of mbufs returned by
 J> soreceive(). If I understand correctly the socket receive buffer may
 J> contain a chain of mbufs with a PKTHDR mbuf as the non-first mbuf? If
 J> m_split() is not intended for this use case I am happy to continue using a
 J> custom version, only asking for my own understanding.
 
 Hmm, can you provide example or code reference?
 
 I may mistake, but AFAIU, the socket receive buffer can contain a chain of
 mbuf chains, linked via m_nextpkt. In these chains first mbufs are pkthdr
 mbufs, but those mbuf that are pointed by m_next can't be pkthdr.
 
 This is how socket buffer look like:
 
 -> [M_PKTHDR mbuf].m_nextpkt->[M_PKTHDR mbuf].m_nextpkt->...
    |                          |
    m_next->[mbuf].m_next->...  \
                                 m_next->...
 
 -- 
 Totus tuus, Glebius.

From: Jacques Fourie <jacques.fourie@gmail.com>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 15:00:35 +0200

 --047d7bb04c9006e41904d8bf64f8
 Content-Type: text/plain; charset=ISO-8859-1
 
 On Mon, Mar 25, 2013 at 2:46 PM, Gleb Smirnoff <glebius@freebsd.org> wrote:
 
 > On Mon, Mar 25, 2013 at 02:34:20PM +0200, Jacques Fourie wrote:
 > J> > Right, I forgot to mention that in my email. In the networking stack
 > it
 > J> > must
 > J> > not happen that a non-first mbuf in chain is pkthdr mbuf.
 > J> >
 > J> In my use case I call m_split() to split a chain of mbufs returned by
 > J> soreceive(). If I understand correctly the socket receive buffer may
 > J> contain a chain of mbufs with a PKTHDR mbuf as the non-first mbuf? If
 > J> m_split() is not intended for this use case I am happy to continue
 > using a
 > J> custom version, only asking for my own understanding.
 >
 > Hmm, can you provide example or code reference?
 >
 > I may mistake, but AFAIU, the socket receive buffer can contain a chain of
 > mbuf chains, linked via m_nextpkt. In these chains first mbufs are pkthdr
 > mbufs, but those mbuf that are pointed by m_next can't be pkthdr.
 >
 > This is how socket buffer look like:
 >
 > -> [M_PKTHDR mbuf].m_nextpkt->[M_PKTHDR mbuf].m_nextpkt->...
 >    |                          |
 >    m_next->[mbuf].m_next->...  \
 >                                 m_next->...
 >
 > --
 > Totus tuus, Glebius.
 >
 I forgot to mention that I'm using TCP. If I follow the code starting from
 sbappendstream() it seems as if m_nextpkt is not used for stream sockets,
 correct? I know that m_nextpkt is used for UDP as can be seen  by following
 the code path starting from sbappendaddr_locked().
 
 Regards,
 Jacques
 
 --047d7bb04c9006e41904d8bf64f8
 Content-Type: text/html; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 <div dir=3D"ltr">On Mon, Mar 25, 2013 at 2:46 PM, Gleb Smirnoff <span dir=
 =3D"ltr">&lt;<a href=3D"mailto:glebius@freebsd.org" target=3D"_blank">glebi=
 us@freebsd.org</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div cla=
 ss=3D"gmail_quote">
 <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
 x #ccc solid;padding-left:1ex">On Mon, Mar 25, 2013 at 02:34:20PM +0200, Ja=
 cques Fourie wrote:<br>
 J&gt; &gt; Right, I forgot to mention that in my email. In the networking s=
 tack it<br>
 J&gt; &gt; must<br>
 J&gt; &gt; not happen that a non-first mbuf in chain is pkthdr mbuf.<br>
 J&gt; &gt;<br>
 J&gt; In my use case I call m_split() to split a chain of mbufs returned by=
 <br>
 J&gt; soreceive(). If I understand correctly the socket receive buffer may<=
 br>
 J&gt; contain a chain of mbufs with a PKTHDR mbuf as the non-first mbuf? If=
 <br>
 J&gt; m_split() is not intended for this use case I am happy to continue us=
 ing a<br>
 J&gt; custom version, only asking for my own understanding.<br>
 <br>
 Hmm, can you provide example or code reference?<br>
 <br>
 I may mistake, but AFAIU, the socket receive buffer can contain a chain of<=
 br>
 mbuf chains, linked via m_nextpkt. In these chains first mbufs are pkthdr<b=
 r>
 mbufs, but those mbuf that are pointed by m_next can&#39;t be pkthdr.<br>
 <br>
 This is how socket buffer look like:<br>
 <br>
 -&gt; [M_PKTHDR mbuf].m_nextpkt-&gt;[M_PKTHDR mbuf].m_nextpkt-&gt;...<br>
 =A0 =A0| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0|<br>
 =A0 =A0m_next-&gt;[mbuf].m_next-&gt;... =A0\<br>
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 m_next-&gt;=
 ...<br>
 <span class=3D"HOEnZb"><font color=3D"#888888"><br>
 --<br>
 Totus tuus, Glebius.<br>
 </font></span></blockquote></div>I forgot to mention that I&#39;m using TCP=
 . If I follow the code starting from sbappendstream() it seems as if m_next=
 pkt is not used for stream sockets, correct? I know that m_nextpkt is used =
 for UDP as can be seen =A0by following the code path starting from sbappend=
 addr_locked().</div>
 <div class=3D"gmail_extra"><br></div><div class=3D"gmail_extra" style>Regar=
 ds,</div><div class=3D"gmail_extra" style>Jacques</div><div class=3D"gmail_=
 extra" style><br></div></div>
 
 --047d7bb04c9006e41904d8bf64f8--

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Jacques Fourie <jacques.fourie@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Mon, 25 Mar 2013 17:16:18 +0400

 On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wrote:
 J> I forgot to mention that I'm using TCP. If I follow the code starting from
 J> sbappendstream() it seems as if m_nextpkt is not used for stream sockets,
 J> correct? I know that m_nextpkt is used for UDP as can be seen  by following
 J> the code path starting from sbappendaddr_locked().
 
   You are right, again. :) So it looks like socket buffer code produces
 pkthdr mbufs in a middle of a chain. Since usually socket buffer is end
 of mbuf life cycle, this doesn't lead to any undesirable consequences.
 
   I will seek advice with rwatson@, who spend a lot of time on sb code,
 on how should we deal with this. Whether m_split() should be smart enough
 to exploit this or not.
 
 -- 
 Totus tuus, Glebius.

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Jacques Fourie <jacques.fourie@gmail.com>
Cc: bug-followup@freebsd.org
Subject: Re: kern/176144: m_split
Date: Fri, 29 Mar 2013 13:16:20 +0400

 --qo7zVO9a9OQ5oQtr
 Content-Type: text/plain; charset=koi8-r
 Content-Disposition: inline
 
   Jacques,
 
   again sorry for delay.
 
 On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wrote:
 J> I forgot to mention that I'm using TCP. If I follow the code starting from
 J> sbappendstream() it seems as if m_nextpkt is not used for stream sockets,
 J> correct? I know that m_nextpkt is used for UDP as can be seen  by following
 J> the code path starting from sbappendaddr_locked().
 
 I have discussed that with Robert Watson and Andre Oppermann. The
 conclusion is that we do not guarantee packet boundaries in the
 SOCK_STREAM socket buffers. Moreover, absence of M_PKTHDR on any
 not first mbuf should be an invariant. And actually in FreeBSD 7.0
 there were even code that guaranteed this invariant. However, later
 before 7.1 I have removed it, since ng_ksocket(4) relies on that
 wrong behaviour.
 
 So, the conclusion is:
 
 1) The patch I've sent you last time is a considered a final
    version. I've attached it once again. Can you please review
    and acknowledge it?
 
 2) Your code should not rely on packet boundaries in a stream socket
    buffer.
 
 3) I should somehow fix ng_ksocket(), and return back the code
    that enforces the invariant.
 
 -- 
 Totus tuus, Glebius.
 
 --qo7zVO9a9OQ5oQtr
 Content-Type: text/x-diff; charset=koi8-r
 Content-Disposition: attachment; filename="uipc_mbuf.c.diff"
 
 Index: uipc_mbuf.c
 ===================================================================
 --- uipc_mbuf.c	(revision 248873)
 +++ uipc_mbuf.c	(working copy)
 @@ -1197,8 +1197,17 @@ m_split(struct mbuf *m0, int len0, int wait)
  	if (m == NULL)
  		return (NULL);
  	remain = m->m_len - len;
 -	if (m0->m_flags & M_PKTHDR) {
 +	if (m0->m_flags & M_PKTHDR && remain == 0) {
  		n = m_gethdr(wait, m0->m_type);
 +			return (NULL);
 +		n->m_next = m->m_next;
 +		m->m_next = NULL;
 +		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
 +		n->m_pkthdr.len = m0->m_pkthdr.len - len0;
 +		m0->m_pkthdr.len = len0;
 +		return (n);
 +	} else if (m0->m_flags & M_PKTHDR) {
 +		n = m_gethdr(wait, m0->m_type);
  		if (n == NULL)
  			return (NULL);
  		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
 
 --qo7zVO9a9OQ5oQtr--

From: Jacques Fourie <jacques.fourie@gmail.com>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: "bug-followup@freebsd.org" <bug-followup@freebsd.org>
Subject: Re: kern/176144: m_split
Date: Fri, 29 Mar 2013 13:03:31 +0200

 On 29 Mar 2013, at 11:16, Gleb Smirnoff <glebius@freebsd.org> wrote:
 
 >  Jacques,
 >
 >  again sorry for delay.
 >
 > On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wrote:
 > J> I forgot to mention that I'm using TCP. If I follow the code starting from
 > J> sbappendstream() it seems as if m_nextpkt is not used for stream sockets,
 > J> correct? I know that m_nextpkt is used for UDP as can be seen  by following
 > J> the code path starting from sbappendaddr_locked().
 >
 > I have discussed that with Robert Watson and Andre Oppermann. The
 > conclusion is that we do not guarantee packet boundaries in the
 > SOCK_STREAM socket buffers. Moreover, absence of M_PKTHDR on any
 > not first mbuf should be an invariant. And actually in FreeBSD 7.0
 > there were even code that guaranteed this invariant. However, later
 > before 7.1 I have removed it, since ng_ksocket(4) relies on that
 > wrong behaviour.
 >
 > So, the conclusion is:
 >
 > 1) The patch I've sent you last time is a considered a final
 >   version. I've attached it once again. Can you please review
 >   and acknowledge it?
 >
 > 2) Your code should not rely on packet boundaries in a stream socket
 >   buffer.
 >
 > 3) I should somehow fix ng_ksocket(), and return back the code
 >   that enforces the invariant.
 >
 > --
 > Totus tuus, Glebius.
 > <uipc_mbuf.c.diff>
 Hi Gleb,
 
 I'm on vacation until Wednesday, will review the patch then. Your
 previous patch could lead to unnecessary mbuf allocations in my use
 case because of M_PKTHDR mbufs that can be in the middle of the chain
 passed to m_split(). I don't mind to keep this micro optimization
 private however. Thanks for the feedback,
 Jacques

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Jacques Fourie <jacques.fourie@gmail.com>
Cc: "bug-followup@freebsd.org" <bug-followup@freebsd.org>
Subject: Re: kern/176144: m_split
Date: Fri, 29 Mar 2013 15:42:31 +0400

 On Fri, Mar 29, 2013 at 01:03:31PM +0200, Jacques Fourie wrote:
 J> > On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wrote:
 J> > J> I forgot to mention that I'm using TCP. If I follow the code starting from
 J> > J> sbappendstream() it seems as if m_nextpkt is not used for stream sockets,
 J> > J> correct? I know that m_nextpkt is used for UDP as can be seen  by following
 J> > J> the code path starting from sbappendaddr_locked().
 J> >
 J> > I have discussed that with Robert Watson and Andre Oppermann. The
 J> > conclusion is that we do not guarantee packet boundaries in the
 J> > SOCK_STREAM socket buffers. Moreover, absence of M_PKTHDR on any
 J> > not first mbuf should be an invariant. And actually in FreeBSD 7.0
 J> > there were even code that guaranteed this invariant. However, later
 J> > before 7.1 I have removed it, since ng_ksocket(4) relies on that
 J> > wrong behaviour.
 J> >
 J> > So, the conclusion is:
 J> >
 J> > 1) The patch I've sent you last time is a considered a final
 J> >   version. I've attached it once again. Can you please review
 J> >   and acknowledge it?
 J> >
 J> > 2) Your code should not rely on packet boundaries in a stream socket
 J> >   buffer.
 J> >
 J> > 3) I should somehow fix ng_ksocket(), and return back the code
 J> >   that enforces the invariant.
 J> >
 J> > --
 J> > Totus tuus, Glebius.
 J> > <uipc_mbuf.c.diff>
 J> Hi Gleb,
 J> 
 J> I'm on vacation until Wednesday, will review the patch then. Your
 J> previous patch could lead to unnecessary mbuf allocations in my use
 J> case because of M_PKTHDR mbufs that can be in the middle of the chain
 J> passed to m_split(). I don't mind to keep this micro optimization
 J> private however. Thanks for the feedback,
 J> Jacques
 
 No problem, I'll wait for a week.
 
 Just re-read my above email then. You can't rely on M_PKTHDR in middle of
 chain. In FreeBSD we used to have a code than cleansed them, and we
 are about to return it back.
 
 -- 
 Totus tuus, Glebius.

From: Jacques Fourie <jacques.fourie@gmail.com>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: "bug-followup@freebsd.org" <bug-followup@freebsd.org>
Subject: Re: kern/176144: m_split
Date: Fri, 29 Mar 2013 13:56:19 +0200

 On 29 Mar 2013, at 13:42, Gleb Smirnoff <glebius@freebsd.org> wrote:
 
 > On Fri, Mar 29, 2013 at 01:03:31PM +0200, Jacques Fourie wrote:
 > J> > On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wrote:
 > J> > J> I forgot to mention that I'm using TCP. If I follow the code starting from
 > J> > J> sbappendstream() it seems as if m_nextpkt is not used for stream sockets,
 > J> > J> correct? I know that m_nextpkt is used for UDP as can be seen  by following
 > J> > J> the code path starting from sbappendaddr_locked().
 > J> >
 > J> > I have discussed that with Robert Watson and Andre Oppermann. The
 > J> > conclusion is that we do not guarantee packet boundaries in the
 > J> > SOCK_STREAM socket buffers. Moreover, absence of M_PKTHDR on any
 > J> > not first mbuf should be an invariant. And actually in FreeBSD 7.0
 > J> > there were even code that guaranteed this invariant. However, later
 > J> > before 7.1 I have removed it, since ng_ksocket(4) relies on that
 > J> > wrong behaviour.
 > J> >
 > J> > So, the conclusion is:
 > J> >
 > J> > 1) The patch I've sent you last time is a considered a final
 > J> >   version. I've attached it once again. Can you please review
 > J> >   and acknowledge it?
 > J> >
 > J> > 2) Your code should not rely on packet boundaries in a stream socket
 > J> >   buffer.
 > J> >
 > J> > 3) I should somehow fix ng_ksocket(), and return back the code
 > J> >   that enforces the invariant.
 > J> >
 > J> > --
 > J> > Totus tuus, Glebius.
 > J> > <uipc_mbuf.c.diff>
 > J> Hi Gleb,
 > J>
 > J> I'm on vacation until Wednesday, will review the patch then. Your
 > J> previous patch could lead to unnecessary mbuf allocations in my use
 > J> case because of M_PKTHDR mbufs that can be in the middle of the chain
 > J> passed to m_split(). I don't mind to keep this micro optimization
 > J> private however. Thanks for the feedback,
 > J> Jacques
 >
 > No problem, I'll wait for a week.
 >
 > Just re-read my above email then. You can't rely on M_PKTHDR in middle of
 > chain. In FreeBSD we used to have a code than cleansed them, and we
 > are about to return it back.
 >
 > --
 > Totus tuus, Glebius.
 I'm not relying on that, just saying that it can happen in my current
 use case because there is no guarantee that stream socket buffers
 won't contain a M_PKTHDR mbuf somewhere. If that's not going to be the
 case in a while all the better.
 
 Thanks,
 Jacques
State-Changed-From-To: open->patched 
State-Changed-By: glebius 
State-Changed-When: Fri Mar 29 14:08:27 UTC 2013 
State-Changed-Why:  
Fixed in head. Thanks for submission! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176144 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/176144: commit references a PR
Date: Fri, 29 Mar 2013 14:10:49 +0000 (UTC)

 Author: glebius
 Date: Fri Mar 29 14:10:40 2013
 New Revision: 248887
 URL: http://svnweb.freebsd.org/changeset/base/248887
 
 Log:
   Fix bug in m_split() in a case when split len matches len of the
   first mbuf, and the first mbuf is M_PKTHDR.
   
   PR:		kern/176144
   Submitted by:	Jacques Fourie <jacques.fourie gmail.com>
 
 Modified:
   head/sys/kern/uipc_mbuf.c
 
 Modified: head/sys/kern/uipc_mbuf.c
 ==============================================================================
 --- head/sys/kern/uipc_mbuf.c	Fri Mar 29 14:06:04 2013	(r248886)
 +++ head/sys/kern/uipc_mbuf.c	Fri Mar 29 14:10:40 2013	(r248887)
 @@ -1197,7 +1197,16 @@ m_split(struct mbuf *m0, int len0, int w
  	if (m == NULL)
  		return (NULL);
  	remain = m->m_len - len;
 -	if (m0->m_flags & M_PKTHDR) {
 +	if (m0->m_flags & M_PKTHDR && remain == 0) {
 +		n = m_gethdr(wait, m0->m_type);
 +			return (NULL);
 +		n->m_next = m->m_next;
 +		m->m_next = NULL;
 +		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
 +		n->m_pkthdr.len = m0->m_pkthdr.len - len0;
 +		m0->m_pkthdr.len = len0;
 +		return (n);
 +	} else if (m0->m_flags & M_PKTHDR) {
  		n = m_gethdr(wait, m0->m_type);
  		if (n == NULL)
  			return (NULL);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: Jacques Fourie <jacques.fourie@gmail.com>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: "bug-followup@freebsd.org" <bug-followup@freebsd.org>
Subject: Re: kern/176144: m_split
Date: Wed, 3 Apr 2013 11:03:19 +0200

 --047d7bb04c9018696004d97120d1
 Content-Type: text/plain; charset=ISO-8859-1
 
 On Fri, Mar 29, 2013 at 1:56 PM, Jacques Fourie <jacques.fourie@gmail.com>wrote:
 
 > On 29 Mar 2013, at 13:42, Gleb Smirnoff <glebius@freebsd.org> wrote:
 >
 > > On Fri, Mar 29, 2013 at 01:03:31PM +0200, Jacques Fourie wrote:
 > > J> > On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wrote:
 > > J> > J> I forgot to mention that I'm using TCP. If I follow the code
 > starting from
 > > J> > J> sbappendstream() it seems as if m_nextpkt is not used for stream
 > sockets,
 > > J> > J> correct? I know that m_nextpkt is used for UDP as can be seen
 >  by following
 > > J> > J> the code path starting from sbappendaddr_locked().
 > > J> >
 > > J> > I have discussed that with Robert Watson and Andre Oppermann. The
 > > J> > conclusion is that we do not guarantee packet boundaries in the
 > > J> > SOCK_STREAM socket buffers. Moreover, absence of M_PKTHDR on any
 > > J> > not first mbuf should be an invariant. And actually in FreeBSD 7.0
 > > J> > there were even code that guaranteed this invariant. However, later
 > > J> > before 7.1 I have removed it, since ng_ksocket(4) relies on that
 > > J> > wrong behaviour.
 > > J> >
 > > J> > So, the conclusion is:
 > > J> >
 > > J> > 1) The patch I've sent you last time is a considered a final
 > > J> >   version. I've attached it once again. Can you please review
 > > J> >   and acknowledge it?
 > > J> >
 > > J> > 2) Your code should not rely on packet boundaries in a stream socket
 > > J> >   buffer.
 > > J> >
 > > J> > 3) I should somehow fix ng_ksocket(), and return back the code
 > > J> >   that enforces the invariant.
 > > J> >
 > > J> > --
 > > J> > Totus tuus, Glebius.
 > > J> > <uipc_mbuf.c.diff>
 > > J> Hi Gleb,
 > > J>
 > > J> I'm on vacation until Wednesday, will review the patch then. Your
 > > J> previous patch could lead to unnecessary mbuf allocations in my use
 > > J> case because of M_PKTHDR mbufs that can be in the middle of the chain
 > > J> passed to m_split(). I don't mind to keep this micro optimization
 > > J> private however. Thanks for the feedback,
 > > J> Jacques
 > >
 > > No problem, I'll wait for a week.
 > >
 > > Just re-read my above email then. You can't rely on M_PKTHDR in middle of
 > > chain. In FreeBSD we used to have a code than cleansed them, and we
 > > are about to return it back.
 > >
 > > --
 > > Totus tuus, Glebius.
 > I'm not relying on that, just saying that it can happen in my current
 > use case because there is no guarantee that stream socket buffers
 > won't contain a M_PKTHDR mbuf somewhere. If that's not going to be the
 > case in a while all the better.
 >
 > Thanks,
 > Jacques
 >
 Hi Gleb,
 
 I had a look at the fix in head and I'm happy with your fix given that
 FreeBSD will cleanse M_PKTHDR mbufs from the middle of mbuf chains as noted
 above.
 
 Thanks,
 Jacques
 
 --047d7bb04c9018696004d97120d1
 Content-Type: text/html; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 <div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
 _quote">On Fri, Mar 29, 2013 at 1:56 PM, Jacques Fourie <span dir=3D"ltr">&=
 lt;<a href=3D"mailto:jacques.fourie@gmail.com" target=3D"_blank">jacques.fo=
 urie@gmail.com</a>&gt;</span> wrote:<br>
 <blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
 x #ccc solid;padding-left:1ex"><div class=3D"HOEnZb"><div class=3D"h5">On 2=
 9 Mar 2013, at 13:42, Gleb Smirnoff &lt;<a href=3D"mailto:glebius@freebsd.o=
 rg">glebius@freebsd.org</a>&gt; wrote:<br>
 
 <br>
 &gt; On Fri, Mar 29, 2013 at 01:03:31PM +0200, Jacques Fourie wrote:<br>
 &gt; J&gt; &gt; On Mon, Mar 25, 2013 at 03:00:35PM +0200, Jacques Fourie wr=
 ote:<br>
 &gt; J&gt; &gt; J&gt; I forgot to mention that I&#39;m using TCP. If I foll=
 ow the code starting from<br>
 &gt; J&gt; &gt; J&gt; sbappendstream() it seems as if m_nextpkt is not used=
  for stream sockets,<br>
 &gt; J&gt; &gt; J&gt; correct? I know that m_nextpkt is used for UDP as can=
  be seen =A0by following<br>
 &gt; J&gt; &gt; J&gt; the code path starting from sbappendaddr_locked().<br=
 >
 &gt; J&gt; &gt;<br>
 &gt; J&gt; &gt; I have discussed that with Robert Watson and Andre Opperman=
 n. The<br>
 &gt; J&gt; &gt; conclusion is that we do not guarantee packet boundaries in=
  the<br>
 &gt; J&gt; &gt; SOCK_STREAM socket buffers. Moreover, absence of M_PKTHDR o=
 n any<br>
 &gt; J&gt; &gt; not first mbuf should be an invariant. And actually in Free=
 BSD 7.0<br>
 &gt; J&gt; &gt; there were even code that guaranteed this invariant. Howeve=
 r, later<br>
 &gt; J&gt; &gt; before 7.1 I have removed it, since ng_ksocket(4) relies on=
  that<br>
 &gt; J&gt; &gt; wrong behaviour.<br>
 &gt; J&gt; &gt;<br>
 &gt; J&gt; &gt; So, the conclusion is:<br>
 &gt; J&gt; &gt;<br>
 &gt; J&gt; &gt; 1) The patch I&#39;ve sent you last time is a considered a =
 final<br>
 &gt; J&gt; &gt; =A0 version. I&#39;ve attached it once again. Can you pleas=
 e review<br>
 &gt; J&gt; &gt; =A0 and acknowledge it?<br>
 &gt; J&gt; &gt;<br>
 &gt; J&gt; &gt; 2) Your code should not rely on packet boundaries in a stre=
 am socket<br>
 &gt; J&gt; &gt; =A0 buffer.<br>
 &gt; J&gt; &gt;<br>
 &gt; J&gt; &gt; 3) I should somehow fix ng_ksocket(), and return back the c=
 ode<br>
 &gt; J&gt; &gt; =A0 that enforces the invariant.<br>
 &gt; J&gt; &gt;<br>
 &gt; J&gt; &gt; --<br>
 &gt; J&gt; &gt; Totus tuus, Glebius.<br>
 &gt; J&gt; &gt; &lt;uipc_mbuf.c.diff&gt;<br>
 &gt; J&gt; Hi Gleb,<br>
 &gt; J&gt;<br>
 &gt; J&gt; I&#39;m on vacation until Wednesday, will review the patch then.=
  Your<br>
 &gt; J&gt; previous patch could lead to unnecessary mbuf allocations in my =
 use<br>
 &gt; J&gt; case because of M_PKTHDR mbufs that can be in the middle of the =
 chain<br>
 &gt; J&gt; passed to m_split(). I don&#39;t mind to keep this micro optimiz=
 ation<br>
 &gt; J&gt; private however. Thanks for the feedback,<br>
 &gt; J&gt; Jacques<br>
 &gt;<br>
 &gt; No problem, I&#39;ll wait for a week.<br>
 &gt;<br>
 &gt; Just re-read my above email then. You can&#39;t rely on M_PKTHDR in mi=
 ddle of<br>
 &gt; chain. In FreeBSD we used to have a code than cleansed them, and we<br=
 >
 &gt; are about to return it back.<br>
 &gt;<br>
 &gt; --<br>
 &gt; Totus tuus, Glebius.<br>
 </div></div>I&#39;m not relying on that, just saying that it can happen in =
 my current<br>
 use case because there is no guarantee that stream socket buffers<br>
 won&#39;t contain a M_PKTHDR mbuf somewhere. If that&#39;s not going to be =
 the<br>
 case in a while all the better.<br>
 <br>
 Thanks,<br>
 Jacques<br>
 </blockquote></div>Hi Gleb,</div><div class=3D"gmail_extra"><br></div><div =
 class=3D"gmail_extra" style>I had a look at the fix in head and I&#39;m hap=
 py with your fix given that FreeBSD will cleanse M_PKTHDR mbufs from the mi=
 ddle of mbuf chains as noted above.</div>
 <div class=3D"gmail_extra" style><br></div><div class=3D"gmail_extra" style=
 >Thanks,</div><div class=3D"gmail_extra" style>Jacques</div></div>
 
 --047d7bb04c9018696004d97120d1--
State-Changed-From-To: patched->closed 
State-Changed-By: glebius 
State-Changed-When: Wed Jan 22 09:26:28 UTC 2014 
State-Changed-Why:  
Fixed in 10.0-RELEASE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=176144 
>Unformatted:
