From patchwork Thu Apr 8 07:35:10 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhu Yi X-Patchwork-Id: 91237 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o387UtRr004023 for ; Thu, 8 Apr 2010 07:30:58 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758580Ab0DHHaz (ORCPT ); Thu, 8 Apr 2010 03:30:55 -0400 Received: from mga11.intel.com ([192.55.52.93]:22859 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758436Ab0DHHav (ORCPT ); Thu, 8 Apr 2010 03:30:51 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 08 Apr 2010 00:30:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.52,169,1270450800"; d="scan'208";a="556046851" Received: from yzhu-mobl0.sh.intel.com (HELO localhost.localdomain) ([10.239.36.37]) by fmsmga002.fm.intel.com with ESMTP; 08 Apr 2010 00:30:41 -0700 From: Zhu Yi To: linville@tuxdriver.com Cc: linux-wireless@vger.kernel.org, Zhu Yi , Johannes Berg Subject: [PATCH] mac80211: delay skb linearising in rx decryption Date: Thu, 8 Apr 2010 15:35:10 +0800 Message-Id: <1270712110-10370-1-git-send-email-yi.zhu@intel.com> X-Mailer: git-send-email 1.6.0.4 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 08 Apr 2010 07:30:58 +0000 (UTC) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c0ad7e8..052cee0 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -820,7 +820,7 @@ ieee80211_rx_h_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 *hdr = (struct ieee80211_hdr *)skb->data; int keyidx; int hdrlen; ieee80211_rx_result result = RX_DROP_UNUSABLE; @@ -861,11 +861,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) if (!(rx->flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; - if (skb_linearize(rx->skb)) - return RX_DROP_UNUSABLE; - - hdr = (struct ieee80211_hdr *)skb->data; - /* start without a key */ rx->key = NULL; @@ -906,6 +901,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) rx->key = key; return RX_CONTINUE; } else { + u8 keyid; /* * The device doesn't give us the IV so we won't be * able to look up the key. That's ok though, we @@ -928,7 +924,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) * no need to call ieee80211_wep_get_keyidx, * it verifies a bunch of things we've done already */ - keyidx = rx->skb->data[hdrlen + 3] >> 6; + skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1); + keyidx = keyid >> 6; rx->key = rcu_dereference(rx->sdata->keys[keyidx]); @@ -949,6 +946,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) return RX_DROP_MONITOR; } + if (skb_linearize(rx->skb)) + return RX_DROP_UNUSABLE; + + hdr = (struct ieee80211_hdr *)rx->skb->data; + /* Check for weak IVs if possible */ if (rx->sta && rx->key->conf.alg == ALG_WEP && ieee80211_is_data(hdr->frame_control) &&