| Summary: | Incomplete cleanup in the netgraph bridge shutdown function | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Richard Andrades <richard> |
| Component: | kern | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->closed Fixed in revisions 1.12 (-current) and 1.1.2.4 (-stable). |
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.