DF-3502 / fix.diff
--- a/sys/netgraph/fec/ng_fec.c +++ b/sys/netgraph/fec/ng_fec.c @@ -20,6 +20,7 @@ */ static int *ng_fec_units = NULL; static int ng_fec_units_len = 0; static int ng_units_in_use = 0; +static int ng_fec_armed = 0; /* fec nodes arming ng_ether_input_p */ @@ -455,6 +456,10 @@ ng_fec_delport(struct ng_fec_private *priv, char *iface) /* Stop interface */ bifp->if_flags &= ~IFF_UP; + /* Stop claiming this member's RX path: clear our IFP2NG pointer, + * otherwise it dangles after the node is freed and ng_fec_input + * dereferences freed memory on the next armed RX frame. */ + ac = (struct arpcom *)bifp; + if (ac->ac_netgraph == (void *)priv->node) + ac->ac_netgraph = NULL; bifp->if_ioctl(bifp, SIOCSIFFLAGS, NULL, NULL); /* Restore MAC address. */ @@ -1131,7 +1136,8 @@ ng_fec_constructor(node_p *nodep) /* Grab hold of the ether_input pipe. */ if (ng_ether_input_p == NULL) ng_ether_input_p = ng_fec_input; + ng_fec_armed++; /* Attach the interface */ ether_ifattach(ifp, priv->arpcom.ac_enaddr, NULL); @@ -1231,8 +1237,9 @@ ng_fec_rmnode(node_p node) ng_cutlinks(node); ng_unname(node); - if (ng_ether_input_p != NULL) - ng_ether_input_p = NULL; + if (--ng_fec_armed <= 0 && ng_ether_input_p == ng_fec_input) + ng_ether_input_p = NULL; ether_ifdetach(&priv->arpcom.ac_if); |