diff options
Diffstat (limited to 'package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch')
-rw-r--r-- | package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch | 313 |
1 files changed, 0 insertions, 313 deletions
diff --git a/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch b/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch deleted file mode 100644 index b536126d38..0000000000 --- a/package/kernel/mac80211/patches/subsys/385-mac80211-add-fragment-cache-to-sta_info.patch +++ /dev/null @@ -1,313 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Tue, 11 May 2021 20:02:47 +0200 -Subject: [PATCH] mac80211: add fragment cache to sta_info - -Prior patches protected against fragmentation cache attacks -by coloring keys, but this shows that it can lead to issues -when multiple stations use the same sequence number. Add a -fragment cache to struct sta_info (in addition to the one in -the interface) to separate fragments for different stations -properly. - -This then automatically clear most of the fragment cache when a -station disconnects (or reassociates) from an AP, or when client -interfaces disconnect from the network, etc. - -On the way, also fix the comment there since this brings us in line -with the recommendation in 802.11-2016 ("An AP should support ..."). -Additionally, remove a useless condition (since there's no problem -purging an already empty list). - -Cc: stable@vger.kernel.org -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -50,12 +50,6 @@ struct ieee80211_local; - #define IEEE80211_ENCRYPT_HEADROOM 8 - #define IEEE80211_ENCRYPT_TAILROOM 18 - --/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent -- * reception of at least three fragmented frames. This limit can be increased -- * by changing this define, at the cost of slower frame reassembly and -- * increased memory use (about 2 kB of RAM per entry). */ --#define IEEE80211_FRAGMENT_MAX 4 -- - /* power level hasn't been configured (or set to automatic) */ - #define IEEE80211_UNSET_POWER_LEVEL INT_MIN - -@@ -88,19 +82,6 @@ extern const u8 ieee80211_ac_to_qos_mask - - #define IEEE80211_MAX_NAN_INSTANCE_ID 255 - --struct ieee80211_fragment_entry { -- struct sk_buff_head skb_list; -- unsigned long first_frag_time; -- u16 seq; -- u16 extra_len; -- u16 last_frag; -- u8 rx_queue; -- bool check_sequential_pn; /* needed for CCMP/GCMP */ -- u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ -- unsigned int key_color; --}; -- -- - struct ieee80211_bss { - u32 device_ts_beacon, device_ts_presp; - -@@ -912,9 +893,7 @@ struct ieee80211_sub_if_data { - - char name[IFNAMSIZ]; - -- /* Fragment table for host-based reassembly */ -- struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; -- unsigned int fragment_next; -+ struct ieee80211_fragment_cache frags; - - /* TID bitmap for NoAck policy */ - u16 noack_map; -@@ -2329,4 +2308,7 @@ u32 ieee80211_calc_expected_tx_airtime(s - #define debug_noinline - #endif - -+void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache); -+void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache); -+ - #endif /* IEEE80211_I_H */ ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -8,7 +8,7 @@ - * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> - * Copyright 2013-2014 Intel Mobile Communications GmbH - * Copyright (c) 2016 Intel Deutschland GmbH -- * Copyright (C) 2018-2020 Intel Corporation -+ * Copyright (C) 2018-2021 Intel Corporation - */ - #include <linux/slab.h> - #include <linux/kernel.h> -@@ -679,16 +679,12 @@ static void ieee80211_set_multicast_list - */ - static void ieee80211_teardown_sdata(struct ieee80211_sub_if_data *sdata) - { -- int i; -- - /* free extra data */ - ieee80211_free_keys(sdata, false); - - ieee80211_debugfs_remove_netdev(sdata); - -- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) -- __skb_queue_purge(&sdata->fragments[i].skb_list); -- sdata->fragment_next = 0; -+ ieee80211_destroy_frag_cache(&sdata->frags); - - if (ieee80211_vif_is_mesh(&sdata->vif)) - ieee80211_mesh_teardown_sdata(sdata); -@@ -2038,8 +2034,7 @@ int ieee80211_if_add(struct ieee80211_lo - sdata->wdev.wiphy = local->hw.wiphy; - sdata->local = local; - -- for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) -- skb_queue_head_init(&sdata->fragments[i].skb_list); -+ ieee80211_init_frag_cache(&sdata->frags); - - INIT_LIST_HEAD(&sdata->key_list); - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2133,19 +2133,34 @@ ieee80211_rx_h_decrypt(struct ieee80211_ - return result; - } - -+void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(cache->entries); i++) -+ skb_queue_head_init(&cache->entries[i].skb_list); -+} -+ -+void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(cache->entries); i++) -+ __skb_queue_purge(&cache->entries[i].skb_list); -+} -+ - static inline struct ieee80211_fragment_entry * --ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, -+ieee80211_reassemble_add(struct ieee80211_fragment_cache *cache, - unsigned int frag, unsigned int seq, int rx_queue, - struct sk_buff **skb) - { - struct ieee80211_fragment_entry *entry; - -- entry = &sdata->fragments[sdata->fragment_next++]; -- if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) -- sdata->fragment_next = 0; -+ entry = &cache->entries[cache->next++]; -+ if (cache->next >= IEEE80211_FRAGMENT_MAX) -+ cache->next = 0; - -- if (!skb_queue_empty(&entry->skb_list)) -- __skb_queue_purge(&entry->skb_list); -+ __skb_queue_purge(&entry->skb_list); - - __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ - *skb = NULL; -@@ -2160,14 +2175,14 @@ ieee80211_reassemble_add(struct ieee8021 - } - - static inline struct ieee80211_fragment_entry * --ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, -+ieee80211_reassemble_find(struct ieee80211_fragment_cache *cache, - unsigned int frag, unsigned int seq, - int rx_queue, struct ieee80211_hdr *hdr) - { - struct ieee80211_fragment_entry *entry; - int i, idx; - -- idx = sdata->fragment_next; -+ idx = cache->next; - for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { - struct ieee80211_hdr *f_hdr; - struct sk_buff *f_skb; -@@ -2176,7 +2191,7 @@ ieee80211_reassemble_find(struct ieee802 - if (idx < 0) - idx = IEEE80211_FRAGMENT_MAX - 1; - -- entry = &sdata->fragments[idx]; -+ entry = &cache->entries[idx]; - if (skb_queue_empty(&entry->skb_list) || entry->seq != seq || - entry->rx_queue != rx_queue || - entry->last_frag + 1 != frag) -@@ -2217,6 +2232,7 @@ static bool requires_sequential_pn(struc - static ieee80211_rx_result debug_noinline - ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) - { -+ struct ieee80211_fragment_cache *cache = &rx->sdata->frags; - struct ieee80211_hdr *hdr; - u16 sc; - __le16 fc; -@@ -2238,6 +2254,9 @@ ieee80211_rx_h_defragment(struct ieee802 - goto out_no_led; - } - -+ if (rx->sta) -+ cache = &rx->sta->frags; -+ - if (likely(!ieee80211_has_morefrags(fc) && frag == 0)) - goto out; - -@@ -2256,7 +2275,7 @@ ieee80211_rx_h_defragment(struct ieee802 - - if (frag == 0) { - /* This is the first fragment of a new frame. */ -- entry = ieee80211_reassemble_add(rx->sdata, frag, seq, -+ entry = ieee80211_reassemble_add(cache, frag, seq, - rx->seqno_idx, &(rx->skb)); - if (requires_sequential_pn(rx, fc)) { - int queue = rx->security_idx; -@@ -2284,7 +2303,7 @@ ieee80211_rx_h_defragment(struct ieee802 - /* This is a fragment for a frame that should already be pending in - * fragment cache. Add this fragment to the end of the pending entry. - */ -- entry = ieee80211_reassemble_find(rx->sdata, frag, seq, -+ entry = ieee80211_reassemble_find(cache, frag, seq, - rx->seqno_idx, hdr); - if (!entry) { - I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -4,7 +4,7 @@ - * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> - * Copyright 2013-2014 Intel Mobile Communications GmbH - * Copyright (C) 2015 - 2017 Intel Deutschland GmbH -- * Copyright (C) 2018-2020 Intel Corporation -+ * Copyright (C) 2018-2021 Intel Corporation - */ - - #include <linux/module.h> -@@ -393,6 +393,8 @@ struct sta_info *sta_info_alloc(struct i - - u64_stats_init(&sta->rx_stats.syncp); - -+ ieee80211_init_frag_cache(&sta->frags); -+ - sta->sta_state = IEEE80211_STA_NONE; - - /* Mark TID as unreserved */ -@@ -1103,6 +1105,8 @@ static void __sta_info_destroy_part2(str - - ieee80211_sta_debugfs_remove(sta); - -+ ieee80211_destroy_frag_cache(&sta->frags); -+ - cleanup_single_sta(sta); - } - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -3,7 +3,7 @@ - * Copyright 2002-2005, Devicescape Software, Inc. - * Copyright 2013-2014 Intel Mobile Communications GmbH - * Copyright(c) 2015-2017 Intel Deutschland GmbH -- * Copyright(c) 2020 Intel Corporation -+ * Copyright(c) 2020-2021 Intel Corporation - */ - - #ifndef STA_INFO_H -@@ -439,6 +439,33 @@ struct ieee80211_sta_rx_stats { - }; - - /* -+ * IEEE 802.11-2016 (10.6 "Defragmentation") recommends support for "concurrent -+ * reception of at least one MSDU per access category per associated STA" -+ * on APs, or "at least one MSDU per access category" on other interface types. -+ * -+ * This limit can be increased by changing this define, at the cost of slower -+ * frame reassembly and increased memory use while fragments are pending. -+ */ -+#define IEEE80211_FRAGMENT_MAX 4 -+ -+struct ieee80211_fragment_entry { -+ struct sk_buff_head skb_list; -+ unsigned long first_frag_time; -+ u16 seq; -+ u16 extra_len; -+ u16 last_frag; -+ u8 rx_queue; -+ bool check_sequential_pn; /* needed for CCMP/GCMP */ -+ u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ -+ unsigned int key_color; -+}; -+ -+struct ieee80211_fragment_cache { -+ struct ieee80211_fragment_entry entries[IEEE80211_FRAGMENT_MAX]; -+ unsigned int next; -+}; -+ -+/* - * The bandwidth threshold below which the per-station CoDel parameters will be - * scaled to be more lenient (to prevent starvation of slow stations). This - * value will be scaled by the number of active stations when it is being -@@ -531,6 +558,7 @@ struct ieee80211_sta_rx_stats { - * @status_stats.last_ack_signal: last ACK signal - * @status_stats.ack_signal_filled: last ACK signal validity - * @status_stats.avg_ack_signal: average ACK signal -+ * @frags: fragment cache - */ - struct sta_info { - /* General information, mostly static */ -@@ -639,6 +667,8 @@ struct sta_info { - - struct cfg80211_chan_def tdls_chandef; - -+ struct ieee80211_fragment_cache frags; -+ - /* keep last! */ - struct ieee80211_sta sta; - }; |