aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/352-mac80211-fix-use-after-free-in-defragmentation.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/352-mac80211-fix-use-after-free-in-defragmentation.patch')
-rw-r--r--package/kernel/mac80211/patches/352-mac80211-fix-use-after-free-in-defragmentation.patch50
1 files changed, 50 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/352-mac80211-fix-use-after-free-in-defragmentation.patch b/package/kernel/mac80211/patches/352-mac80211-fix-use-after-free-in-defragmentation.patch
new file mode 100644
index 0000000000..f7472e0a4e
--- /dev/null
+++ b/package/kernel/mac80211/patches/352-mac80211-fix-use-after-free-in-defragmentation.patch
@@ -0,0 +1,50 @@
+From: Johannes Berg <johannes.berg@intel.com>
+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: stable@vger.kernel.org
+Reported-by: Yosef Khyal <yosefx.khyal@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- 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;
+ }
+