Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mac80211: remove ieee80211_get_hdr_info

Do the check for sufficient skb->len explicitly and pass a pointer
to the struct ieee80211_hdr directly to the michael_mic calculation.

Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Harvey Harrison and committed by
John W. Linville
8e8862b7 f14df804

+35 -41
+15 -5
net/mac80211/michael.c
··· 8 8 */ 9 9 #include <linux/types.h> 10 10 #include <linux/bitops.h> 11 + #include <linux/ieee80211.h> 11 12 #include <asm/unaligned.h> 12 13 13 14 #include "michael.h" ··· 27 26 mctx->l += mctx->r; 28 27 } 29 28 30 - static void michael_mic_hdr(struct michael_mic_ctx *mctx, 31 - const u8 *key, const u8 *da, const u8 *sa, u8 priority) 29 + static void michael_mic_hdr(struct michael_mic_ctx *mctx, const u8 *key, 30 + struct ieee80211_hdr *hdr) 32 31 { 32 + u8 *da, *sa, tid; 33 + 34 + da = ieee80211_get_DA(hdr); 35 + sa = ieee80211_get_SA(hdr); 36 + if (ieee80211_is_data_qos(hdr->frame_control)) 37 + tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; 38 + else 39 + tid = 0; 40 + 33 41 mctx->l = get_unaligned_le32(key); 34 42 mctx->r = get_unaligned_le32(key + 4); 35 43 ··· 50 40 michael_block(mctx, get_unaligned_le16(&da[4]) | 51 41 (get_unaligned_le16(sa) << 16)); 52 42 michael_block(mctx, get_unaligned_le32(&sa[2])); 53 - michael_block(mctx, priority); 43 + michael_block(mctx, tid); 54 44 } 55 45 56 - void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, 46 + void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, 57 47 const u8 *data, size_t data_len, u8 *mic) 58 48 { 59 49 u32 val; 60 50 size_t block, blocks, left; 61 51 struct michael_mic_ctx mctx; 62 52 63 - michael_mic_hdr(&mctx, key, da, sa, priority); 53 + michael_mic_hdr(&mctx, key, hdr); 64 54 65 55 /* Real data */ 66 56 blocks = data_len / 4;
+1 -1
net/mac80211/michael.h
··· 18 18 u32 l, r; 19 19 }; 20 20 21 - void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, 21 + void michael_mic(const u8 *key, struct ieee80211_hdr *hdr, 22 22 const u8 *data, size_t data_len, u8 *mic); 23 23 24 24 #endif /* MICHAEL_H */
+19 -35
net/mac80211/wpa.c
··· 21 21 #include "aes_ccm.h" 22 22 #include "wpa.h" 23 23 24 - static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, 25 - u8 *qos_tid, u8 **data, size_t *data_len) 26 - { 27 - struct ieee80211_hdr *hdr; 28 - size_t hdrlen; 29 - __le16 fc; 30 - 31 - hdr = (struct ieee80211_hdr *)skb->data; 32 - fc = hdr->frame_control; 33 - 34 - hdrlen = ieee80211_hdrlen(fc); 35 - 36 - *sa = ieee80211_get_SA(hdr); 37 - *da = ieee80211_get_DA(hdr); 38 - 39 - *data = skb->data + hdrlen; 40 - *data_len = skb->len - hdrlen; 41 - 42 - if (ieee80211_is_data_qos(fc)) 43 - *qos_tid = (*ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK) | 0x80; 44 - else 45 - *qos_tid = 0; 46 - 47 - return skb->len < hdrlen ? -1 : 0; 48 - } 49 - 50 - 51 24 ieee80211_tx_result 52 25 ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) 53 26 { 54 - u8 *data, *sa, *da, *key, *mic, qos_tid, key_offset; 27 + u8 *data, *key, *mic, key_offset; 55 28 size_t data_len; 29 + unsigned int hdrlen; 30 + struct ieee80211_hdr *hdr; 56 31 u16 fc; 57 32 struct sk_buff *skb = tx->skb; 58 33 int authenticator; ··· 40 65 !WLAN_FC_DATA_PRESENT(fc)) 41 66 return TX_CONTINUE; 42 67 43 - if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) 68 + hdr = (struct ieee80211_hdr *)skb->data; 69 + hdrlen = ieee80211_hdrlen(hdr->frame_control); 70 + if (skb->len < hdrlen) 44 71 return TX_DROP; 72 + 73 + data = skb->data + hdrlen; 74 + data_len = skb->len - hdrlen; 45 75 46 76 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 47 77 !(tx->flags & IEEE80211_TX_FRAGMENTED) && ··· 77 97 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; 78 98 key = &tx->key->conf.key[key_offset]; 79 99 mic = skb_put(skb, MICHAEL_MIC_LEN); 80 - michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 100 + michael_mic(key, hdr, data, data_len, mic); 81 101 82 102 return TX_CONTINUE; 83 103 } ··· 86 106 ieee80211_rx_result 87 107 ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) 88 108 { 89 - u8 *data, *sa, *da, *key = NULL, qos_tid, key_offset; 109 + u8 *data, *key = NULL, key_offset; 90 110 size_t data_len; 111 + unsigned int hdrlen; 112 + struct ieee80211_hdr *hdr; 91 113 u16 fc; 92 114 u8 mic[MICHAEL_MIC_LEN]; 93 115 struct sk_buff *skb = rx->skb; ··· 108 126 !(rx->fc & IEEE80211_FCTL_PROTECTED) || !WLAN_FC_DATA_PRESENT(fc)) 109 127 return RX_CONTINUE; 110 128 111 - if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) 112 - || data_len < MICHAEL_MIC_LEN) 129 + hdr = (struct ieee80211_hdr *)skb->data; 130 + hdrlen = ieee80211_hdrlen(hdr->frame_control); 131 + if (skb->len < hdrlen + MICHAEL_MIC_LEN) 113 132 return RX_DROP_UNUSABLE; 114 133 115 - data_len -= MICHAEL_MIC_LEN; 134 + data = skb->data + hdrlen; 135 + data_len = skb->len - hdrlen - MICHAEL_MIC_LEN; 116 136 117 137 #if 0 118 138 authenticator = fc & IEEE80211_FCTL_TODS; /* FIX */ ··· 127 143 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY : 128 144 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; 129 145 key = &rx->key->conf.key[key_offset]; 130 - michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 146 + michael_mic(key, hdr, data, data_len, mic); 131 147 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { 132 148 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 133 149 return RX_DROP_UNUSABLE;