--- a/sys/dev/netif/sbsh/if_sbsh.c +++ b/sys/dev/netif/sbsh/if_sbsh.c @@ -665,8 +665,11 @@ encap_frame(struct sbsh_softc *sc, struct mbuf *m_head) done = 0; do { if (m->m_len < 5 || cur_tbd == ((sc->head_tdesc - 1) & 0x7f)) { if ((m_head = repack(sc, m_head)) != NULL) goto look_for_nonzero; else + /* drop the frame instead of leaking it */ + m_freem(m_head); return; } @@ -699,6 +702,11 @@ static struct mbuf * repack(struct sbsh_softc *sc, struct mbuf *m) { struct mbuf *m_new; + /* A repacked packet smaller than 5 bytes would re-trigger the + * repack condition in encap_frame() forever (infinite alloc/free + * spin while holding if_serializer). Drop such frames instead. */ + if (m->m_pkthdr.len < 5) + return (NULL); + MGETHDR(m_new, M_NOWAIT, MT_DATA); if (!m_new) { if_printf (&sc->arpcom.ac_if, "unable to get mbuf.\n");