aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index be9abc2e6348..6e7d6d48fe1e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -825,6 +825,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
825 ieee80211_rx_result result = RX_DROP_UNUSABLE; 825 ieee80211_rx_result result = RX_DROP_UNUSABLE;
826 struct ieee80211_key *stakey = NULL; 826 struct ieee80211_key *stakey = NULL;
827 int mmie_keyidx = -1; 827 int mmie_keyidx = -1;
828 __le16 fc;
828 829
829 /* 830 /*
830 * Key selection 101 831 * Key selection 101
@@ -866,13 +867,15 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
866 if (rx->sta) 867 if (rx->sta)
867 stakey = rcu_dereference(rx->sta->key); 868 stakey = rcu_dereference(rx->sta->key);
868 869
869 if (!ieee80211_has_protected(hdr->frame_control)) 870 fc = hdr->frame_control;
871
872 if (!ieee80211_has_protected(fc))
870 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb); 873 mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
871 874
872 if (!is_multicast_ether_addr(hdr->addr1) && stakey) { 875 if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
873 rx->key = stakey; 876 rx->key = stakey;
874 /* Skip decryption if the frame is not protected. */ 877 /* Skip decryption if the frame is not protected. */
875 if (!ieee80211_has_protected(hdr->frame_control)) 878 if (!ieee80211_has_protected(fc))
876 return RX_CONTINUE; 879 return RX_CONTINUE;
877 } else if (mmie_keyidx >= 0) { 880 } else if (mmie_keyidx >= 0) {
878 /* Broadcast/multicast robust management frame / BIP */ 881 /* Broadcast/multicast robust management frame / BIP */
@@ -884,7 +887,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
884 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) 887 mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
885 return RX_DROP_MONITOR; /* unexpected BIP keyidx */ 888 return RX_DROP_MONITOR; /* unexpected BIP keyidx */
886 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]); 889 rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
887 } else if (!ieee80211_has_protected(hdr->frame_control)) { 890 } else if (!ieee80211_has_protected(fc)) {
888 /* 891 /*
889 * The frame was not protected, so skip decryption. However, we 892 * The frame was not protected, so skip decryption. However, we
890 * need to set rx->key if there is a key that could have been 893 * need to set rx->key if there is a key that could have been
@@ -892,7 +895,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
892 * have been expected. 895 * have been expected.
893 */ 896 */
894 struct ieee80211_key *key = NULL; 897 struct ieee80211_key *key = NULL;
895 if (ieee80211_is_mgmt(hdr->frame_control) && 898 if (ieee80211_is_mgmt(fc) &&
896 is_multicast_ether_addr(hdr->addr1) && 899 is_multicast_ether_addr(hdr->addr1) &&
897 (key = rcu_dereference(rx->sdata->default_mgmt_key))) 900 (key = rcu_dereference(rx->sdata->default_mgmt_key)))
898 rx->key = key; 901 rx->key = key;
@@ -914,7 +917,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
914 (status->flag & RX_FLAG_IV_STRIPPED)) 917 (status->flag & RX_FLAG_IV_STRIPPED))
915 return RX_CONTINUE; 918 return RX_CONTINUE;
916 919
917 hdrlen = ieee80211_hdrlen(hdr->frame_control); 920 hdrlen = ieee80211_hdrlen(fc);
918 921
919 if (rx->skb->len < 8 + hdrlen) 922 if (rx->skb->len < 8 + hdrlen)
920 return RX_DROP_UNUSABLE; /* TODO: count this? */ 923 return RX_DROP_UNUSABLE; /* TODO: count this? */
@@ -947,19 +950,17 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
947 950
948 if (skb_linearize(rx->skb)) 951 if (skb_linearize(rx->skb))
949 return RX_DROP_UNUSABLE; 952 return RX_DROP_UNUSABLE;
950 953 /* the hdr variable is invalid now! */
951 hdr = (struct ieee80211_hdr *)rx->skb->data;
952
953 /* Check for weak IVs if possible */
954 if (rx->sta && rx->key->conf.alg == ALG_WEP &&
955 ieee80211_is_data(hdr->frame_control) &&
956 (!(status->flag & RX_FLAG_IV_STRIPPED) ||
957 !(status->flag & RX_FLAG_DECRYPTED)) &&
958 ieee80211_wep_is_weak_iv(rx->skb, rx->key))
959 rx->sta->wep_weak_iv_count++;
960 954
961 switch (rx->key->conf.alg) { 955 switch (rx->key->conf.alg) {
962 case ALG_WEP: 956 case ALG_WEP:
957 /* Check for weak IVs if possible */
958 if (rx->sta && ieee80211_is_data(fc) &&
959 (!(status->flag & RX_FLAG_IV_STRIPPED) ||
960 !(status->flag & RX_FLAG_DECRYPTED)) &&
961 ieee80211_wep_is_weak_iv(rx->skb, rx->key))
962 rx->sta->wep_weak_iv_count++;
963
963 result = ieee80211_crypto_wep_decrypt(rx); 964 result = ieee80211_crypto_wep_decrypt(rx);
964 break; 965 break;
965 case ALG_TKIP: 966 case ALG_TKIP:
@@ -1852,7 +1853,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
1852 return RX_QUEUED; 1853 return RX_QUEUED;
1853 } 1854 }
1854 1855
1855 return RX_CONTINUE; 1856 /*
1857 * After this point, we only want management frames,
1858 * so we can drop all remaining control frames to
1859 * cooked monitor interfaces.
1860 */
1861 return RX_DROP_MONITOR;
1856} 1862}
1857 1863
1858static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, 1864static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,