mac80211: detect and drop incoming packets with invalid CCMP packet numbers to fix connection hangs on some devices
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@26795 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
1a91588812
commit
c80372fee7
|
@ -0,0 +1,46 @@
|
|||
--- a/net/mac80211/key.h
|
||||
+++ b/net/mac80211/key.h
|
||||
@@ -86,6 +86,7 @@ struct ieee80211_key {
|
||||
* Management frames.
|
||||
*/
|
||||
u8 rx_pn[NUM_RX_DATA_QUEUES + 1][6];
|
||||
+ u8 rx_invalid_pn[NUM_RX_DATA_QUEUES + 1];
|
||||
struct crypto_cipher *tfm;
|
||||
u32 replays; /* dot11RSNAStatsCCMPReplays */
|
||||
/* scratch buffers for virt_to_page() (crypto API) */
|
||||
--- a/net/mac80211/wpa.c
|
||||
+++ b/net/mac80211/wpa.c
|
||||
@@ -407,6 +407,13 @@ ieee80211_crypto_ccmp_encrypt(struct iee
|
||||
return TX_CONTINUE;
|
||||
}
|
||||
|
||||
+static inline u64 pn_to_u64(u8 *data)
|
||||
+{
|
||||
+ u64 pn = get_unaligned_be32(data + 2);
|
||||
+ pn |= ((u64) get_unaligned_be16(data)) << 32;
|
||||
+ return pn;
|
||||
+}
|
||||
+
|
||||
|
||||
ieee80211_rx_result
|
||||
ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
|
||||
@@ -419,6 +426,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||
u8 pn[CCMP_PN_LEN];
|
||||
int data_len;
|
||||
int queue;
|
||||
+ u64 diff;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
|
||||
@@ -452,6 +460,11 @@ ieee80211_crypto_ccmp_decrypt(struct iee
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
+ diff = pn_to_u64(pn) - pn_to_u64(key->u.ccmp.rx_pn[queue]);
|
||||
+ if (diff > 1000 && key->u.ccmp.rx_invalid_pn[queue]++ < 10)
|
||||
+ return RX_DROP_UNUSABLE;
|
||||
+
|
||||
+ key->u.ccmp.rx_invalid_pn[queue] = 0;
|
||||
memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
|
||||
|
||||
/* Remove CCMP header and MIC */
|
Loading…
Reference in New Issue