{
        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;
        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;
 
                        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
                 * 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]);
 
                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) &&