DF-3530 / fix.diff
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); |