DragonFlyBSD Kernel Audit
DF-0528 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph/fec/ng_fec.c b/sys/netgraph/fec/ng_fec.c
@@ -1216,17 +1216,24 @@
 	const priv_p priv = node->private;
 	struct ng_fec_bundle *b;
 	struct ng_fec_portlist	*p;
-	char ifname[IFNAMSIZ];
 
 	b = &priv->fec_bundle;
 	ng_fec_stop(&priv->arpcom.ac_if);
 
 	while (!TAILQ_EMPTY(&b->ng_fec_ports)) {
 		p = TAILQ_FIRST(&b->ng_fec_ports);
-		ksprintf(ifname, "%s",
-		    p->fec_if->if_xname); /* XXX: strings */
-		ng_fec_delport(priv, ifname);
+		/*
+		 * Unlink and free the port entry directly instead of calling
+		 * ng_fec_delport(), which re-resolves the member interface via
+		 * ifunit().  If the underlying interface has already been
+		 * destroyed, ifunit() returns NULL and delport() returns ENOENT
+		 * without removing the entry, looping here forever.  We also
+		 * avoid the dangling p->fec_if->if_xname dereference.
+		 */
+		TAILQ_REMOVE(&b->ng_fec_ports, p, fec_list);
+		kfree(p, M_NETGRAPH);
 	}
+	b->fec_ifcnt = 0;
 
 	ng_cutlinks(node);
 	ng_unname(node);