Subject: Re: kern/30098: nmap causes kern panic in m_pulldown on sparc64
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Martin Husemann <martin@duskware.de>
List: netbsd-bugs
Date: 05/03/2005 11:11:01
The following reply was made to PR kern/30098; it has been noted by GNATS.

From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/30098: nmap causes kern panic in m_pulldown on sparc64
Date: Tue, 3 May 2005 13:10:24 +0200

 So, what happens is that m_pulldown in kern/uipc_mbuf2.c:180 does this:
 
         if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen &&
             !sharedcluster) {
                 n->m_next->m_data -= hlen;
                 n->m_next->m_len += hlen;
                 memcpy(mtod(n->m_next, caddr_t), mtod(n, caddr_t) + off, hlen);
                 n->m_len -= hlen;
                 n = n->m_next;
                 off = 0;
                 goto ok;
         }
 
 Now in our case n->m_next has 8 bytes, and enough leading space. So we go into
 this if, and prepend 8 bytes from n to n->m_next. That makes it contain 16
 bytes, but we want 20 - the "goto ok" is optimistic, we need to check for
 this case and pull down something from the next mbuf, right?
 
 A brute force fix is to disable this optimization:
 
 Index: uipc_mbuf2.c
 ===================================================================
 RCS file: /cvsroot/src/sys/kern/uipc_mbuf2.c,v
 retrieving revision 1.17
 diff -u -r1.17 uipc_mbuf2.c
 --- uipc_mbuf2.c	21 Jul 2004 12:09:43 -0000	1.17
 +++ uipc_mbuf2.c	3 May 2005 11:02:33 -0000
 @@ -178,7 +178,7 @@
  		goto ok;
  	}
  	if ((off == 0 || offp) && M_LEADINGSPACE(n->m_next) >= hlen &&
 -	    !sharedcluster) {
 +	    !sharedcluster && n->m_next->m_len >= tlen) {
  		n->m_next->m_data -= hlen;
  		n->m_next->m_len += hlen;
  		memcpy(mtod(n->m_next, caddr_t), mtod(n, caddr_t) + off, hlen);
 
 Or is this worth a real fix?
 
 Martin