diff options
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 38 |
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 | ||
1858 | static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, | 1864 | static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata, |