| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- From: Johannes Berg <[email protected]>
- Date: Mon, 3 Nov 2014 14:29:09 +0100
- Subject: [PATCH] mac80211: fix use-after-free in defragmentation
- Upon receiving the last fragment, all but the first fragment
- are freed, but the multicast check for statistics at the end
- of the function refers to the current skb (the last fragment)
- causing a use-after-free bug.
- Since multicast frames cannot be fragmented and we check for
- this early in the function, just modify that check to also
- do the accounting to fix the issue.
- Cc: [email protected]
- Reported-by: Yosef Khyal <[email protected]>
- Signed-off-by: Johannes Berg <[email protected]>
- ---
- --- a/net/mac80211/rx.c
- +++ b/net/mac80211/rx.c
- @@ -1678,11 +1678,14 @@ ieee80211_rx_h_defragment(struct ieee802
- sc = le16_to_cpu(hdr->seq_ctrl);
- frag = sc & IEEE80211_SCTL_FRAG;
-
- - if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
- - is_multicast_ether_addr(hdr->addr1))) {
- - /* not fragmented */
- + if (likely(!ieee80211_has_morefrags(fc) && frag == 0))
- + goto out;
- +
- + if (is_multicast_ether_addr(hdr->addr1)) {
- + rx->local->dot11MulticastReceivedFrameCount++;
- goto out;
- }
- +
- I802_DEBUG_INC(rx->local->rx_handlers_fragments);
-
- if (skb_linearize(rx->skb))
- @@ -1775,10 +1778,7 @@ ieee80211_rx_h_defragment(struct ieee802
- out:
- if (rx->sta)
- rx->sta->rx_packets++;
- - if (is_multicast_ether_addr(hdr->addr1))
- - rx->local->dot11MulticastReceivedFrameCount++;
- - else
- - ieee80211_led_rx(rx->local);
- + ieee80211_led_rx(rx->local);
- return RX_CONTINUE;
- }
-
|