Subject: goto bad in ip_output()
To: None <tech-net@netbsd.org>
From: enami tsugutomo <enami@but-b.or.jp>
List: tech-net
Date: 10/13/2003 22:45:45
Two `goto bad' in ip_output() near the end is doubtful.

`if (error) goto bad' after the ip_fragment() just leads mbuf leak if
it returns ENOBUFS.  the for() loop after ip_fragment() can also
handle error case well.  And the leak actually hangs NFS.

The `goto bad' in the if-clasue just above ip_fragment() call is
doubtful.  Why cleanups aren't necessary?

enami.

Index: ip_output.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/ip_output.c,v
retrieving revision 1.123
diff -c -r1.123 ip_output.c
*** ip_output.c	3 Oct 2003 20:56:11 -0000	1.123
--- ip_output.c	13 Oct 2003 13:31:04 -0000
***************
*** 797,809 ****
  			*mtu_p = mtu;
  		error = EMSGSIZE;
  		ipstat.ips_cantfrag++;
! 		goto bad;
  	}
  
  	error = ip_fragment(m, ifp, mtu);
- 	if (error)
- 		goto bad;
  
  	for (; m; m = m0) {
  		m0 = m->m_nextpkt;
  		m->m_nextpkt = 0;
--- 797,808 ----
  			*mtu_p = mtu;
  		error = EMSGSIZE;
  		ipstat.ips_cantfrag++;
! 		goto done;
  	}
  
  	error = ip_fragment(m, ifp, mtu);
  
+ 	/* Send or free */
  	for (; m; m = m0) {
  		m0 = m->m_nextpkt;
  		m->m_nextpkt = 0;