| From a71fd9dac23613d96ba3c05619a8ef4fd6cdf9b9 Mon Sep 17 00:00:00 2001 |
| From: Jouni Malinen <j@w1.fi> |
| Date: Tue, 28 May 2019 01:46:43 +0300 |
| Subject: mac80211: Do not use stack memory with scatterlist for GMAC |
| |
| From: Jouni Malinen <j@w1.fi> |
| |
| commit a71fd9dac23613d96ba3c05619a8ef4fd6cdf9b9 upstream. |
| |
| ieee80211_aes_gmac() uses the mic argument directly in sg_set_buf() and |
| that does not allow use of stack memory (e.g., BUG_ON() is hit in |
| sg_set_buf() with CONFIG_DEBUG_SG). BIP GMAC TX side is fine for this |
| since it can use the skb data buffer, but the RX side was using a stack |
| variable for deriving the local MIC value to compare against the |
| received one. |
| |
| Fix this by allocating heap memory for the mic buffer. |
| |
| This was found with hwsim test case ap_cipher_bip_gmac_128 hitting that |
| BUG_ON() and kernel panic. |
| |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Jouni Malinen <j@w1.fi> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| net/mac80211/wpa.c | 7 ++++++- |
| 1 file changed, 6 insertions(+), 1 deletion(-) |
| |
| --- a/net/mac80211/wpa.c |
| +++ b/net/mac80211/wpa.c |
| @@ -1169,7 +1169,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct |
| struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
| struct ieee80211_key *key = rx->key; |
| struct ieee80211_mmie_16 *mmie; |
| - u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN]; |
| + u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN]; |
| struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| |
| if (!ieee80211_is_mgmt(hdr->frame_control)) |
| @@ -1200,13 +1200,18 @@ ieee80211_crypto_aes_gmac_decrypt(struct |
| memcpy(nonce, hdr->addr2, ETH_ALEN); |
| memcpy(nonce + ETH_ALEN, ipn, 6); |
| |
| + mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC); |
| + if (!mic) |
| + return RX_DROP_UNUSABLE; |
| if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, |
| skb->data + 24, skb->len - 24, |
| mic) < 0 || |
| crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { |
| key->u.aes_gmac.icverrors++; |
| + kfree(mic); |
| return RX_DROP_UNUSABLE; |
| } |
| + kfree(mic); |
| } |
| |
| memcpy(key->u.aes_gmac.rx_pn, ipn, 6); |