Bug 29150

Summary: Incomplete cleanup in the netgraph bridge shutdown function
Product: Base System Reporter: Richard Andrades <richard>
Component: kernAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   

Description Richard Andrades 2001-07-22 22:40:01 UTC
When a netgraph bridge node is destroyed, the shutdown
functions fails to deregister the callout function, somtimes
leading to a kernel crash (it doesn't happen every time so it
is hard to reproduce).
It also fails to decrement the node's refcount (which was bumped
by by the constructor). Usually (not always) this causes a
memory leak. This one is very easy to find.

Fix: 

FILE: src/sys/netgraph/ng_bridge.c

/* NOTE: This function has been renamed ng_bridge_shutdown in the */
/* current version of FreeBSD */

/*
 * Shutdown node
 */
static int
ng_bridge_rmnode(node_p node)
{
        const priv_p priv = node->private;

        ng_unname(node);
        ng_cutlinks(node);              /* frees all link and host info */
        KASSERT(priv->numLinks == 0 && priv->numHosts == 0,
            ("%s: numLinks=%d numHosts=%d",
            __FUNCTION__, priv->numLinks, priv->numHosts));

        /* Fix to BUG #1 */
        callout_stop(&priv->timer); 
        /* If the callout is not cancelled when the node is */
        /* removed, a timeout sometimes crashes the kernel. */
        /* End of fix to BUG #1 */

        FREE(priv->tab, M_NETGRAPH);
        FREE(priv, M_NETGRAPH);
        node->private = NULL;

        /* Fix to BUG #2 */
        /* The refcount was incremented by 1 in the constructor. It may
        *  have been decremented by 1 by the timeout. If not, do it now.
        *  This must come after callout_reset.
        */
        if(node->refs > 1)
            ng_unref(node); /* Extra one, to compensate for constructor action */
        /* If the refcount is more than one at this point, the node */
        /* is not removed and it causes a memory leak (64 bytes). */
        /* End of Fix to BUG #2 */

        ng_unref(node);
        return (0);
}
How-To-Repeat: The first BUG can be reproduced by repeatedly adding and
removing netgraph bridges. Sooner or later the kernel will 
crash

The second bug can be reproduced by adding and removing a
netgraph bridge.
Comment 1 Archie Cobbs freebsd_committer freebsd_triage 2002-02-01 02:23:24 UTC
State Changed
From-To: open->closed

Fixed in revisions 1.12 (-current) and 1.1.2.4 (-stable).