DF-0580 / fix.diff
diff --git a/sys/netproto/802_11/wlan/ieee80211_input.c b/sys/netproto/802_11/wlan/ieee80211_input.c --- a/sys/netproto/802_11/wlan/ieee80211_input.c +++ b/sys/netproto/802_11/wlan/ieee80211_input.c @@ -247,17 +247,28 @@ } mfrag = m; } else { /* concatenate */ + uint16_t fraglen; + uint16_t seqsave; + m_adj(m, hdrspace); /* strip header */ + /* + * DragonFly's m_cat() may free the source chain's mbufs + * (bcopy + m_free when the fragment data fits the trailing + * space of mfrag's last mbuf). Capture the values we still + * need from the about-to-be-freed fragment BEFORE m_cat(). + */ + fraglen = m->m_pkthdr.len; + seqsave = *(uint16_t *)wh->i_seq; #if defined(__DragonFly__) m_cat(mfrag, m); /* NB: m_cat doesn't update the packet header */ - mfrag->m_pkthdr.len += m->m_pkthdr.len; + mfrag->m_pkthdr.len += fraglen; #else m_catpkt(mfrag, m); #endif /* track last seqnum and fragno */ lwh = mtod(mfrag, struct ieee80211_frame *); - *(uint16_t *) lwh->i_seq = *(uint16_t *) wh->i_seq; + *(uint16_t *) lwh->i_seq = seqsave; } if (more_frag) { /* more to come, save */ ni->ni_rxfragstamp = ticks; |