Fix DF-3277: bridge_delete_span() unlinked the span bif from &sc->sc_iflists[mycpuid] although span bifs are linked on sc->sc_spanlist (bridge_ioctl_addspan, if_bridge.c:1832). Removing the last span entry executed head->tqh_last = elm->tqe_prev against the per-cpu MEMBER list head, leaving sc_iflists[0].tqh_last pointing at &sc->sc_spanlist.tqh_first. The next TAILQ_INSERT_TAIL on the member list (the LINK2 bonding round-robin in bridge_select_unicast, if_bridge.c:2140) then wrote the member bif into sc_spanlist.tqh_first, cross-linking the lists and leading to KASSERT panic / UAF / double free on teardown (reproduced: "panic: bridge_delete_span: not a span interface" after deleting a span port that was a live member). --- a/sys/net/bridge/if_bridge.c +++ b/sys/net/bridge/if_bridge.c @@ -1152,7 +1152,8 @@ bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif) KASSERT(bif->bif_ifp->if_bridge == NULL, ("%s: not a span interface", __func__)); - TAILQ_REMOVE(&sc->sc_iflists[mycpuid], bif, bif_next); + /* Span bifs live on sc_spanlist, not on the per-cpu member lists */ + TAILQ_REMOVE(&sc->sc_spanlist, bif, bif_next); kfree(bif, M_DEVBUF); }