DragonFlyBSD Kernel Audit
DF-0502 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph7/ng_fec.c b/sys/netgraph7/ng_fec.c
--- a/sys/netgraph7/ng_fec.c
+++ b/sys/netgraph7/ng_fec.c
@@ -1332,10 +1332,18 @@
 	b = &priv->fec_bundle;
 	ng_fec_stop(priv->ifp);
 
-	while (!TAILQ_EMPTY(&b->ng_fec_ports)) {
-		p = TAILQ_FIRST(&b->ng_fec_ports);
+	while ((p = TAILQ_FIRST(&b->ng_fec_ports)) != NULL) {
+		/*
+		 * Remove the portlist entry directly.  Do NOT re-resolve via
+		 * ng_fec_delport()/ifunit(): if a member interface has already
+		 * been destroyed, ifunit() returns NULL and delport() returns
+		 * ENOENT without removing the entry, which would loop forever
+		 * here (and p->fec_if would be a dangling pointer).
+		 */
 		ng_fec_ether_cmdmulti(priv->ifp, p, 0);
-		ng_fec_delport(priv, p->fec_if->if_xname);
+		TAILQ_REMOVE(&b->ng_fec_ports, p, fec_list);
+		kfree(p, M_NETGRAPH);
+		b->fec_ifcnt--;
 	}
 
 	ether_ifdetach(priv->ifp);