DragonFlyBSD Kernel Audit
DF-0525 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph/fec/ng_fec.c b/sys/netgraph/fec/ng_fec.c
--- a/sys/netgraph/fec/ng_fec.c
+++ b/sys/netgraph/fec/ng_fec.c
@@ -575,7 +575,14 @@
 	/*
 	 * Note: serializer for parent interface not held on entry, and
 	 * cannot be held during the loop to avoid a deadlock.
+	 *
+	 * The port list itself, however, MUST be protected by the global
+	 * ifnet_lock() -- ng_fec_addport()/ng_fec_delport() mutate the list
+	 * (TAILQ_INSERT_TAIL/TAILQ_REMOVE + kfree()) under ifnet_lock(), so
+	 * iterating it here without that lock races a concurrent
+	 * NGM_FEC_DEL_IFACE and dereferences a freed list node (UAF).
 	 */
+	ifnet_lock();
 	TAILQ_FOREACH(p, &b->ng_fec_ports, fec_list) {
 		bzero((char *)&ifmr, sizeof(ifmr));
 		ifp = p->fec_if;
@@ -610,6 +617,7 @@
 		}
 		ifnet_deserialize_all(ifp);
 	}
+	ifnet_unlock();
 
 	ifp = &priv->arpcom.ac_if;
 	if (ifp->if_flags & IFF_RUNNING)