Fix DF-3278: bridge_fragment() error loop double-free / UAF. M_PREPEND(..., M_NOWAIT) frees the mbuf chain on allocation failure (sys/sys/mbuf.h:463-479), so after the first failure the loop's 'else m_freem(m)' re-frees fragment #1 for every remaining iteration and the loop increment dereferences freed memory. Free the remainder of the chain exactly once and stop walking it. --- a/sys/net/bridge/if_bridge.c +++ b/sys/net/bridge/if_bridge.c @@ -4386,6 +4386,7 @@ bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh, /* walk the chain and re-add the Ethernet header */ for (m0 = m; m0; m0 = m0->m_nextpkt) { if (error == 0) { + struct mbuf *next; if (snap) { M_PREPEND(m0, sizeof(struct llc), M_NOWAIT); if (m0 == NULL) { @@ -4402,9 +4403,13 @@ bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh, } bcopy(eh, mtod(m0, caddr_t), ETHER_HDR_LEN); } else { - m_freem(m); + /* + * A previous fragment failed (and was freed by + * M_PREPEND); free the remainder of the chain + * exactly once and stop. + */ + next = m0->m_nextpkt; + m0->m_nextpkt = NULL; + m_freem(m0); + m0 = next; } }