aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2010-04-08 03:35:10 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-09 13:43:09 -0400
commit39184b151cbe5ce9f1487190ac4244f69bf6a04b (patch)
treec3dc45e8053ff3066c7a94a3d5a6dfb736be7b5f /net
parent1805a34fa33b6284ab8139dd43779b94de58669a (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')
-rw-r--r--net/mac80211/rx.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d08ede44ac7..8ee7db19326 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) &&