⬢ DragonFlyBSD Kernel Audit
DF-3530 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/netgraph/ether/ng_ether.c b/sys/netgraph/ether/ng_ether.c
--- a/sys/netgraph/ether/ng_ether.c
+++ b/sys/netgraph/ether/ng_ether.c
@@ -204,10 +204,11 @@
 ng_ether_input(struct ifnet *ifp, struct mbuf **mp)
 {
 	const node_p node = IFP2NG(ifp);
-	const priv_p priv = node->private;
+	/* DF-3530: node/private can be NULL mid-teardown (ng_ether_detach) */
+	const priv_p priv = (node != NULL) ? node->private : NULL;
 
 	/* If "lower" hook not connected, let packet continue */
-	if (priv->lower == NULL || priv->lowerOrphan)
+	if (priv == NULL || priv->lower == NULL || priv->lowerOrphan)
 		return;
 	ng_ether_input2(node, mp);
 }
@@ -220,10 +221,11 @@
 ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m)
 {
 	const node_p node = IFP2NG(ifp);
-	const priv_p priv = node->private;
+	/* DF-3530: node/private can be NULL mid-teardown (ng_ether_detach) */
+	const priv_p priv = (node != NULL) ? node->private : NULL;
 
 	/* If "orphan" hook not connected, let packet continue */
-	if (priv->lower == NULL || !priv->lowerOrphan) {
+	if (priv == NULL || priv->lower == NULL || !priv->lowerOrphan) {
 		m_freem(m);
 		return;
 	}
@@ -258,12 +260,13 @@
 ng_ether_output(struct ifnet *ifp, struct mbuf **mp)
 {
 	const node_p node = IFP2NG(ifp);
-	const priv_p priv = node->private;
+	/* DF-3530: node/private can be NULL mid-teardown (ng_ether_detach) */
+	const priv_p priv = (node != NULL) ? node->private : NULL;
 	meta_p meta = NULL;
 	int error = 0;
 
 	/* If "upper" hook not connected, let packet continue */
-	if (priv->upper == NULL)
+	if (priv == NULL || priv->upper == NULL)
 		return (0);
 
 	/* Send it out "upper" hook */
@@ -503,7 +506,13 @@
 ng_ether_rcvdata(hook_p hook, struct mbuf *m, meta_p meta)
 {
 	const node_p node = hook->node;
-	const priv_p priv = node->private;
+	const priv_p priv = (node != NULL) ? node->private : NULL;
+
+	/* DF-3530: private is freed and NULL'd during teardown */
+	if (priv == NULL) {
+		NG_FREE_DATA(m, meta);
+		return (ENXIO);
+	}
 
 	if (hook == priv->lower)
 		return ng_ether_rcv_lower(node, m, meta);