Subject: kern/3986: m_split() doesn't restore length of mbuf chain on failure.
To: None <gnats-bugs@gnats.netbsd.org>
From: None <koji@math.human.nagoya-u.ac.jp>
List: netbsd-bugs
Date: 08/14/1997 20:14:15
>Number:         3986
>Category:       kern
>Synopsis:       m_split() doesn't restore length of mbuf chain on failure.
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Aug 14 06:20:02 1997
>Last-Modified:
>Originator:     Koji Imada - je4owb/2
>Organization:
Mathematics Group of Graduate School of Human
	Infomatics, Nagoya University, Japan.
>Release:        19970813
>Environment:
	
System: NetBSD bimota 1.2G NetBSD 1.2G (BIMOTA) #: Wed Jul 2 01:36:36 JST 1997 koji@ducati:/mnt2/NetBSD/work/src-ufs-mod/sys/arch/i386/compile/BIMOTA i386


>Description:
	m_split() doesn't restore m_pkthdr.len to original length when 
	error happened.
>How-To-Repeat:
	Just look code.
>Fix:
	apply following patch.

Index: sys/kern/uipc_mbuf.c
===================================================================
RCS file: /mnt2/NetBSD/cvsroot/netbsd/sys/kern/uipc_mbuf.c,v
retrieving revision 1.1.1.4
diff -c -r1.1.1.4 uipc_mbuf.c
*** uipc_mbuf.c	1997/06/23 16:26:44	1.1.1.4
--- uipc_mbuf.c	1997/08/03 07:34:44
***************
*** 608,614 ****
  	int len0, wait;
  {
  	register struct mbuf *m, *n;
! 	unsigned len = len0, remain;
  
  	for (m = m0; m && len > m->m_len; m = m->m_next)
  		len -= m->m_len;
--- 608,614 ----
  	int len0, wait;
  {
  	register struct mbuf *m, *n;
! 	unsigned len = len0, remain, len_save;
  
  	for (m = m0; m && len > m->m_len; m = m->m_next)
  		len -= m->m_len;
***************
*** 621,626 ****
--- 621,627 ----
  			return (0);
  		n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
  		n->m_pkthdr.len = m0->m_pkthdr.len - len0;
+ 		len_save = m0->m_pkthdr.len;
  		m0->m_pkthdr.len = len0;
  		if (m->m_flags & M_EXT)
  			goto extpacket;
***************
*** 630,635 ****
--- 631,637 ----
  			n->m_next = m_split(m, len, wait);
  			if (n->m_next == 0) {
  				(void) m_free(n);
+ 				m0->m_pkthdr.len = len_save;
  				return (0);
  			} else
  				return (n);

>Audit-Trail:
>Unformatted: