From dwmalone@maths.tcd.ie  Tue May  9 11:11:50 2000
Return-Path: <dwmalone@maths.tcd.ie>
Received: from salmon.maths.tcd.ie (salmon.maths.tcd.ie [134.226.81.11])
	by hub.freebsd.org (Postfix) with SMTP id 1CB3037B5C0
	for <freebsd-gnats-submit@freebsd.org>; Tue,  9 May 2000 11:11:45 -0700 (PDT)
	(envelope-from dwmalone@maths.tcd.ie)
Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP
          id <aa03940@salmon>; 9 May 2000 19:11:42 +0100 (BST)
Message-Id: <200005091911.aa59278@walton.maths.tcd.ie>
Date: Tue, 9 May 2000 19:11:42 +0100 (BST)
From: dwmalone@maths.tcd.ie
Sender: dwmalone@maths.tcd.ie
Reply-To: dwmalone@maths.tcd.ie
To: FreeBSD-gnats-submit@freebsd.org
Subject: Checking freeing of mbufs.
X-Send-Pr-Version: 3.2

>Number:         18471
>Category:       kern
>Synopsis:       mbuf and mbuf clusters can be freed multiple times
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 09 11:20:00 PDT 2000
>Closed-Date:    Sun Jun 11 09:42:38 PDT 2000
>Last-Modified:  Sun Jun 11 09:42:58 PDT 2000
>Originator:     David Malone
>Release:        FreeBSD 3.4-STABLE i386
>Organization:
School of Mathematics, Trinity College, Dublin, Ireland.
>Environment:

3.X, 4.X, 5.X and probably earlier.

>Description:

The code for freeing mbuf clusters and mbufs doesn't check if the
object is already free before freeing it. While this shouldn't
happen it makes debugging difficult when it does, as we found while
trying to debug some problems with the netatalk code.

It would be better if the kernel paniced at the time of the second
free, as opposed to some time later when the entry which has been
freed twice gets reused while still in use!

>How-To-Repeat:

Write code which doesn't track it's mbufs carefully enough, and try
to debug.

>Fix:
	
I've been running a machine tracking current at home with the
following KASSERTs added and INVARIENTS on. I've seen no problems
with them.

Index: mbuf.h
===================================================================
RCS file: /cvs/FreeBSD-CVS/src/sys/sys/mbuf.h,v
retrieving revision 1.47
diff -u -r1.47 mbuf.h
--- mbuf.h	2000/04/19 01:24:26	1.47
+++ mbuf.h	2000/04/22 20:11:49
@@ -381,6 +381,7 @@
 #define	MCLFREE1(p) do {						\
 	union mcluster *_mp = (union mcluster *)(p);			\
 									\
+	KASSERT(mclrefcnt[mtocl(_mp)] > 0, ("freeing free cluster"));	\
 	if (--mclrefcnt[mtocl(_mp)] == 0) {				\
 		_mp->mcl_next = mclfree;				\
 		mclfree = _mp;						\
@@ -415,6 +416,7 @@
 #define	MFREE(m, n) MBUFLOCK(						\
 	struct mbuf *_mm = (m);						\
 									\
+	KASSERT(_mm->m_type != MT_FREE, ("freeing free mbuf"));		\
 	mbstat.m_mtypes[_mm->m_type]--;					\
 	if (_mm->m_flags & M_EXT)					\
 		MEXTFREE1(m);						\


>Release-Note:
>Audit-Trail:

From: Jin Guojun (FTG staff) <jin@george.lbl.gov>
To: FreeBSD-gnats-submit@FreeBSD.ORG, dwmalone@maths.tcd.ie
Cc:  
Subject: Re: kern/18471: Checking freeing of mbufs.
Date: Tue, 9 May 2000 11:29:55 -0700 (PDT)

 > It would be better if the kernel paniced at the time of the second
 > free, as opposed to some time later when the entry which has been
 > freed twice gets reused while still in use!
 
 I disagree to panic at this point. The better fixing is just printing
 out some error message and do nothing for refreeing code. Whoever writes
 such driver code will know what happens.
 
 	-Jin
 

From: David Malone <dwmalone@maths.tcd.ie>
To: Jin Guojun (FTG staff) <jin@george.lbl.gov>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/18471: Checking freeing of mbufs. 
Date: Wed, 10 May 2000 07:54:54 +0100

 > > It would be better if the kernel paniced at the time of the second
 > > free, as opposed to some time later when the entry which has been
 > > freed twice gets reused while still in use!
 
 > I disagree to panic at this point. The better fixing is just printing
 > out some error message and do nothing for refreeing code. Whoever writes
 > such driver code will know what happens.
 
 That wouldn't really be consistant with the other reference counters
 in the kernel (vnode reference counters would be the main example
 in my mind). At the stage when this happens the kernel has definitely
 done something wrong - possibly having corrupted in data. So a
 panic seems apropriate.
 
 It isn't clear to me what useful message you could print to help
 diganose the problem. Neither the address, nor the contents of the
 mbuf would be that useful. A stack trace would probably be useful
 - but a kernel dump would definitely be. Maybe I've missed something,
 but...
 
 	David.
 

From: Bosko Milekic <bmilekic@dsuper.net>
To: dwmalone@maths.tcd.ie
Cc: jin@george.lbl.gov, FreeBSD-gnats-submit@FreeBSD.ORG
Subject: Re: kern/18471: Checking freeing of mbufs.
Date: Tue, 16 May 2000 13:15:03 -0400 (EDT)

 	Indeed, David is correct when he argues that this should be a panic,
   especially since it's a KASSERT().
 	Without even considering the other troubles the [now confused]
   calling code will run into, just look at what actually happens at the
   mcluster free routine: the "freed" cluster is attached to the mclfree
   list, which is essentially singly linked. When you free a cluster already
   in the free list, you'll basically "lose" all the clusters sitting after
   that one cluster on the list. This then becomes virtually a "leak" and
   the system is royally borked.
   	Somebody please commit this code.
 
   --Bosko
 
 --
  Bosko Milekic * pages.infinit.net/bmilekic/index.html * www.technokratis.com
  bmilekic@dsuper.net * bmilekic@technokratis.com * b.milekic@marianopolis.edu
 
  "Give a man a fish and he will eat for a day. Teach him how
   to fish, and he will sit in a boat and drink beer all day."
 
 
 
State-Changed-From-To: open->closed 
State-Changed-By: jlemon 
State-Changed-When: Sun Jun 11 09:42:38 PDT 2000 
State-Changed-Why:  
Patch applied, thanks! 

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