diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 30 |
1 files changed, 21 insertions, 9 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d052f4004829..bf21e92a6b9c 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -630,15 +630,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
630 | * possible. | 630 | * possible. |
631 | */ | 631 | */ |
632 | 632 | ||
633 | if (!ieee80211_has_protected(hdr->frame_control)) { | ||
634 | if (!ieee80211_is_mgmt(hdr->frame_control) || | ||
635 | rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP)) | ||
636 | return RX_CONTINUE; | ||
637 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | ||
638 | if (mmie_keyidx < 0) | ||
639 | return RX_CONTINUE; | ||
640 | } | ||
641 | |||
642 | /* | 633 | /* |
643 | * No point in finding a key and decrypting if the frame is neither | 634 | * No point in finding a key and decrypting if the frame is neither |
644 | * addressed to us nor a multicast frame. | 635 | * addressed to us nor a multicast frame. |
@@ -649,8 +640,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
649 | if (rx->sta) | 640 | if (rx->sta) |
650 | stakey = rcu_dereference(rx->sta->key); | 641 | stakey = rcu_dereference(rx->sta->key); |
651 | 642 | ||
643 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
644 | mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); | ||
645 | |||
652 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { | 646 | if (!is_multicast_ether_addr(hdr->addr1) && stakey) { |
653 | rx->key = stakey; | 647 | rx->key = stakey; |
648 | /* Skip decryption if the frame is not protected. */ | ||
649 | if (!ieee80211_has_protected(hdr->frame_control)) | ||
650 | return RX_CONTINUE; | ||
654 | } else if (mmie_keyidx >= 0) { | 651 | } else if (mmie_keyidx >= 0) { |
655 | /* Broadcast/multicast robust management frame / BIP */ | 652 | /* Broadcast/multicast robust management frame / BIP */ |
656 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && | 653 | if ((rx->status->flag & RX_FLAG_DECRYPTED) && |
@@ -661,6 +658,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
661 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) | 658 | mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) |
662 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ | 659 | return RX_DROP_MONITOR; /* unexpected BIP keyidx */ |
663 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); | 660 | rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); |
661 | } else if (!ieee80211_has_protected(hdr->frame_control)) { | ||
662 | /* | ||
663 | * The frame was not protected, so skip decryption. However, we | ||
664 | * need to set rx->key if there is a key that could have been | ||
665 | * used so that the frame may be dropped if encryption would | ||
666 | * have been expected. | ||
667 | */ | ||
668 | struct ieee80211_key *key = NULL; | ||
669 | if (ieee80211_is_mgmt(hdr->frame_control) && | ||
670 | is_multicast_ether_addr(hdr->addr1) && | ||
671 | (key = rcu_dereference(rx->sdata->default_mgmt_key))) | ||
672 | rx->key = key; | ||
673 | else if ((key = rcu_dereference(rx->sdata->default_key))) | ||
674 | rx->key = key; | ||
675 | return RX_CONTINUE; | ||
664 | } else { | 676 | } else { |
665 | /* | 677 | /* |
666 | * The device doesn't give us the IV so we won't be | 678 | * The device doesn't give us the IV so we won't be |