summaryrefslogtreecommitdiffstats
path: root/net/mac80211/wep.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-12 13:49:14 +0100
committerJohn W. Linville <linville@tuxdriver.com>2012-03-13 14:54:17 -0400
commita8286911881948c7a2ecc63ee4224c258cce2da3 (patch)
treea35566503b81c654db55857f42fe9664d0aab3af /net/mac80211/wep.c
parent617bbde878604adfcd557fc2a8952f77ab4ebd95 (diff)
mac80211: linearize SKBs as needed for crypto
Not linearizing every SKB will help actually pass non-linear SKBs all the way up when on an encrypted connection. For now, linearize TKIP completely as it is lower performance and I don't quite grok all the details. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/wep.c')
-rw-r--r--net/mac80211/wep.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5cd87ba11bb..7aa31bbfaa3 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -284,22 +284,27 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
struct sk_buff *skb = rx->skb;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ __le16 fc = hdr->frame_control;
- if (!ieee80211_is_data(hdr->frame_control) &&
- !ieee80211_is_auth(hdr->frame_control))
+ if (!ieee80211_is_data(fc) && !ieee80211_is_auth(fc))
return RX_CONTINUE;
if (!(status->flag & RX_FLAG_DECRYPTED)) {
+ if (skb_linearize(rx->skb))
+ return RX_DROP_UNUSABLE;
if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
rx->sta->wep_weak_iv_count++;
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
return RX_DROP_UNUSABLE;
} else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
+ if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN))
+ return RX_DROP_UNUSABLE;
if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
rx->sta->wep_weak_iv_count++;
ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
/* remove ICV */
- skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN);
+ if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN))
+ return RX_DROP_UNUSABLE;
}
return RX_CONTINUE;