diff options
Diffstat (limited to 'net/mac80211/wpa.c')
-rw-r--r-- | net/mac80211/wpa.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index d6635f6e5618..9f6fd20374e1 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -79,6 +79,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
79 | struct sk_buff *skb = tx->skb; | 79 | struct sk_buff *skb = tx->skb; |
80 | int authenticator; | 80 | int authenticator; |
81 | int wpa_test = 0; | 81 | int wpa_test = 0; |
82 | int tail; | ||
82 | 83 | ||
83 | fc = tx->fc; | 84 | fc = tx->fc; |
84 | 85 | ||
@@ -98,16 +99,13 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
98 | return TX_CONTINUE; | 99 | return TX_CONTINUE; |
99 | } | 100 | } |
100 | 101 | ||
101 | if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { | 102 | tail = MICHAEL_MIC_LEN; |
102 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 103 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
103 | if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, | 104 | tail += TKIP_ICV_LEN; |
104 | MICHAEL_MIC_LEN + TKIP_ICV_LEN, | 105 | |
105 | GFP_ATOMIC))) { | 106 | if (WARN_ON(skb_tailroom(skb) < tail || |
106 | printk(KERN_DEBUG "%s: failed to allocate more memory " | 107 | skb_headroom(skb) < TKIP_IV_LEN)) |
107 | "for Michael MIC\n", tx->dev->name); | 108 | return TX_DROP; |
108 | return TX_DROP; | ||
109 | } | ||
110 | } | ||
111 | 109 | ||
112 | #if 0 | 110 | #if 0 |
113 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ | 111 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ |
@@ -188,7 +186,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
188 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 186 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
189 | struct ieee80211_key *key = tx->key; | 187 | struct ieee80211_key *key = tx->key; |
190 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 188 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
191 | int hdrlen, len, tailneed; | 189 | int hdrlen, len, tail; |
192 | u16 fc; | 190 | u16 fc; |
193 | u8 *pos; | 191 | u8 *pos; |
194 | 192 | ||
@@ -199,7 +197,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
199 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | 197 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { |
200 | /* hwaccel - with no need for preallocated room for IV/ICV */ | 198 | /* hwaccel - with no need for preallocated room for IV/ICV */ |
201 | info->control.hw_key = &tx->key->conf; | 199 | info->control.hw_key = &tx->key->conf; |
202 | return TX_CONTINUE; | 200 | return 0; |
203 | } | 201 | } |
204 | 202 | ||
205 | fc = le16_to_cpu(hdr->frame_control); | 203 | fc = le16_to_cpu(hdr->frame_control); |
@@ -207,17 +205,13 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
207 | len = skb->len - hdrlen; | 205 | len = skb->len - hdrlen; |
208 | 206 | ||
209 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 207 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
210 | tailneed = 0; | 208 | tail = 0; |
211 | else | 209 | else |
212 | tailneed = TKIP_ICV_LEN; | 210 | tail = TKIP_ICV_LEN; |
213 | 211 | ||
214 | if ((skb_headroom(skb) < TKIP_IV_LEN || | 212 | if (WARN_ON(skb_tailroom(skb) < tail || |
215 | skb_tailroom(skb) < tailneed)) { | 213 | skb_headroom(skb) < TKIP_IV_LEN)) |
216 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 214 | return -1; |
217 | if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed, | ||
218 | GFP_ATOMIC))) | ||
219 | return -1; | ||
220 | } | ||
221 | 215 | ||
222 | pos = skb_push(skb, TKIP_IV_LEN); | 216 | pos = skb_push(skb, TKIP_IV_LEN); |
223 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); | 217 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); |
@@ -432,7 +426,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
432 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 426 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
433 | struct ieee80211_key *key = tx->key; | 427 | struct ieee80211_key *key = tx->key; |
434 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 428 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
435 | int hdrlen, len, tailneed; | 429 | int hdrlen, len, tail; |
436 | u16 fc; | 430 | u16 fc; |
437 | u8 *pos, *pn, *b_0, *aad, *scratch; | 431 | u8 *pos, *pn, *b_0, *aad, *scratch; |
438 | int i; | 432 | int i; |
@@ -445,7 +439,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
445 | /* hwaccel - with no need for preallocated room for CCMP " | 439 | /* hwaccel - with no need for preallocated room for CCMP " |
446 | * header or MIC fields */ | 440 | * header or MIC fields */ |
447 | info->control.hw_key = &tx->key->conf; | 441 | info->control.hw_key = &tx->key->conf; |
448 | return TX_CONTINUE; | 442 | return 0; |
449 | } | 443 | } |
450 | 444 | ||
451 | scratch = key->u.ccmp.tx_crypto_buf; | 445 | scratch = key->u.ccmp.tx_crypto_buf; |
@@ -457,17 +451,13 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
457 | len = skb->len - hdrlen; | 451 | len = skb->len - hdrlen; |
458 | 452 | ||
459 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 453 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
460 | tailneed = 0; | 454 | tail = 0; |
461 | else | 455 | else |
462 | tailneed = CCMP_MIC_LEN; | 456 | tail = CCMP_MIC_LEN; |
463 | 457 | ||
464 | if ((skb_headroom(skb) < CCMP_HDR_LEN || | 458 | if (WARN_ON(skb_tailroom(skb) < tail || |
465 | skb_tailroom(skb) < tailneed)) { | 459 | skb_headroom(skb) < CCMP_HDR_LEN)) |
466 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 460 | return -1; |
467 | if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed, | ||
468 | GFP_ATOMIC))) | ||
469 | return -1; | ||
470 | } | ||
471 | 461 | ||
472 | pos = skb_push(skb, CCMP_HDR_LEN); | 462 | pos = skb_push(skb, CCMP_HDR_LEN); |
473 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 463 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); |