diff options
author | Zhu Yi <yi.zhu@intel.com> | 2010-04-08 03:35:10 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-09 13:43:09 -0400 |
commit | 39184b151cbe5ce9f1487190ac4244f69bf6a04b (patch) | |
tree | c3dc45e8053ff3066c7a94a3d5a6dfb736be7b5f /net/mac80211/rx.c | |
parent | 1805a34fa33b6284ab8139dd43779b94de58669a (diff) |
mac80211: delay skb linearising in rx decryption
We delay the skb linearising in ieee80211_rx_h_decrypt so that
frames do not require software decryption are not linearized. We
are safe to do this because ieee80211_get_mmie_keyidx() only
requires to touch nonlinear data for management frames, which are
already linearized before getting here.
Cc: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r-- | net/mac80211/rx.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d08ede44ac7e..8ee7db193269 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -820,7 +820,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
820 | { | 820 | { |
821 | struct sk_buff *skb = rx->skb; | 821 | struct sk_buff *skb = rx->skb; |
822 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 822 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
823 | struct ieee80211_hdr *hdr; | 823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
824 | int keyidx; | 824 | int keyidx; |
825 | int hdrlen; | 825 | int hdrlen; |
826 | ieee80211_rx_result result = RX_DROP_UNUSABLE; | 826 | ieee80211_rx_result result = RX_DROP_UNUSABLE; |
@@ -861,11 +861,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
861 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 861 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
862 | return RX_CONTINUE; | 862 | return RX_CONTINUE; |
863 | 863 | ||
864 | if (skb_linearize(rx->skb)) | ||
865 | return RX_DROP_UNUSABLE; | ||
866 | |||
867 | hdr = (struct ieee80211_hdr *)skb->data; | ||
868 | |||
869 | /* start without a key */ | 864 | /* start without a key */ |
870 | rx->key = NULL; | 865 | rx->key = NULL; |
871 | 866 | ||
@@ -906,6 +901,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
906 | rx->key = key; | 901 | rx->key = key; |
907 | return RX_CONTINUE; | 902 | return RX_CONTINUE; |
908 | } else { | 903 | } else { |
904 | u8 keyid; | ||
909 | /* | 905 | /* |
910 | * The device doesn't give us the IV so we won't be | 906 | * The device doesn't give us the IV so we won't be |
911 | * able to look up the key. That's ok though, we | 907 | * able to look up the key. That's ok though, we |
@@ -928,7 +924,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
928 | * no need to call ieee80211_wep_get_keyidx, | 924 | * no need to call ieee80211_wep_get_keyidx, |
929 | * it verifies a bunch of things we've done already | 925 | * it verifies a bunch of things we've done already |
930 | */ | 926 | */ |
931 | keyidx = rx->skb->data[hdrlen + 3] >> 6; | 927 | skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); |
928 | keyidx = keyid >> 6; | ||
932 | 929 | ||
933 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); | 930 | rx->key = rcu_dereference(rx->sdata->keys[keyidx]); |
934 | 931 | ||
@@ -949,6 +946,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
949 | return RX_DROP_MONITOR; | 946 | return RX_DROP_MONITOR; |
950 | } | 947 | } |
951 | 948 | ||
949 | if (skb_linearize(rx->skb)) | ||
950 | return RX_DROP_UNUSABLE; | ||
951 | |||
952 | hdr = (struct ieee80211_hdr *)rx->skb->data; | ||
953 | |||
952 | /* Check for weak IVs if possible */ | 954 | /* Check for weak IVs if possible */ |
953 | if (rx->sta && rx->key->conf.alg == ALG_WEP && | 955 | if (rx->sta && rx->key->conf.alg == ALG_WEP && |
954 | ieee80211_is_data(hdr->frame_control) && | 956 | ieee80211_is_data(hdr->frame_control) && |