Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2881826pxj; Mon, 31 May 2021 13:32:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzoZotYevyf+BMUw6YTy5G5lxDbdXkGNOaUuGkiSPDyy9tzfk4el8nabSBMr0JZIvzW0k0F X-Received: by 2002:aa7:d6ca:: with SMTP id x10mr82112edr.182.1622493160961; Mon, 31 May 2021 13:32:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622493160; cv=none; d=google.com; s=arc-20160816; b=XHYN9ErukuUpk0eX2TXkL3v6t9/9yCjBdi17+dVNET8+xYCZIRLdbHo/WTu+7RmFXi QGG2qJrI+hbr4msWRy5lLFrTbvpDFkiMHcv/HMICPS2D0L9sLblb2dWtR/iCfWxCAhLm dBiwwgf4qUFTxPcwufsOWOQxtGp5iD2KX/QxjPXEfP8upLz3qMUNbJG6zoq1d1/wVBOk mquvxEQLKwBN2fhSd55uXECFSphUYO23OkOlyx6h/0WeOB0SGb2Oh351dS8ZTI8iQ0Gs 9QlQNeXKAMVUi6myVlqwpz72jwUGZ+abm2o3Ls2aKUzU66C216zfqyWYOaZJQtooKJL/ aNXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=JZ47XNzX2vJrVN53qhkb8TV8NpR4QO/L+i6l2l6ORyg=; b=Y6E4fgq2XXumtdDET1XotyG0YwV5BPshkeU5Jg1AtyN2mMlbgC8GxRGBvLoXZL16yO WwwVxgYOCqNKXeoaRhScFvJh0Gslse9q7yw2aNJK1OSDSgJ8R4IC1oup+L/2+YmVSgXG Bh29sAQeKpw7qH/BIHtLxkVmf5Od3yHTDrNY27cZvybKIgqOK1+U7B2oz4Sy1O6DLNqG 74iHs8FdJCQJ7iLi/202TKUsHYFwRucrSz2G7x+9hlksXrtgJ7MzBOyVj9fwQ/IMEguB loK6JQQmMnM+zD+0aPz+D9iCtkHf8rhWM9Z2g6/148/CrKKRkcIMV4j3tMHPTHr5nRm8 WyqA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id 8si13135061ejn.615.2021.05.31.13.32.18; Mon, 31 May 2021 13:32:40 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-wireless-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-wireless-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232385AbhEaUdQ (ORCPT + 99 others); Mon, 31 May 2021 16:33:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230385AbhEaUc5 (ORCPT ); Mon, 31 May 2021 16:32:57 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:191:4433::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A0B3AC0613ED; Mon, 31 May 2021 13:30:32 -0700 (PDT) Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.94.2) (envelope-from ) id 1lnoYQ-000F87-PP; Mon, 31 May 2021 22:30:30 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: stable@vger.kernel.org, Johannes Berg Subject: [PATCH v4.9 07/10] mac80211: check defrag PN against current frame Date: Mon, 31 May 2021 22:30:18 +0200 Message-Id: <20210531203021.180010-8-johannes@sipsolutions.net> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531203021.180010-1-johannes@sipsolutions.net> References: <20210531203021.180010-1-johannes@sipsolutions.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg commit bf30ca922a0c0176007e074b0acc77ed345e9990 upstream. As pointed out by Mathy Vanhoef, we implement the RX PN check on fragmented frames incorrectly - we check against the last received PN prior to the new frame, rather than to the one in this frame itself. Prior patches addressed the security issue here, but in order to be able to reason better about the code, fix it to really compare against the current frame's PN, not the last stored one. Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20210511200110.bfbc340ff071.Id0b690e581da7d03d76df90bb0e3fd55930bc8a0@changeid Signed-off-by: Johannes Berg --- net/mac80211/ieee80211_i.h | 11 +++++++++-- net/mac80211/rx.c | 5 ++--- net/mac80211/wpa.c | 12 ++++++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3c61b632dde4..21b35255ecc2 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -221,8 +221,15 @@ struct ieee80211_rx_data { */ int security_idx; - u32 tkip_iv32; - u16 tkip_iv16; + union { + struct { + u32 iv32; + u16 iv16; + } tkip; + struct { + u8 pn[IEEE80211_CCMP_PN_LEN]; + } ccm_gcm; + }; }; struct ieee80211_csa_settings { diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7b9a5ad7ba7c..b1c017faa1ae 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2057,7 +2057,6 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) if (entry->check_sequential_pn) { int i; u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; - int queue; if (!requires_sequential_pn(rx, fc)) return RX_DROP_UNUSABLE; @@ -2072,8 +2071,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) if (pn[i]) break; } - queue = rx->security_idx; - rpn = rx->key->u.ccmp.rx_pn[queue]; + + rpn = rx->ccm_gcm.pn; if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) return RX_DROP_UNUSABLE; memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index c0529c4b60f8..7819a2507d39 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c @@ -162,8 +162,8 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) update_iv: /* update IV in key information to be able to detect replays */ - rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip_iv32; - rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip_iv16; + rx->key->u.tkip.rx[rx->security_idx].iv32 = rx->tkip.iv32; + rx->key->u.tkip.rx[rx->security_idx].iv16 = rx->tkip.iv16; return RX_CONTINUE; @@ -289,8 +289,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) key, skb->data + hdrlen, skb->len - hdrlen, rx->sta->sta.addr, hdr->addr1, hwaccel, rx->security_idx, - &rx->tkip_iv32, - &rx->tkip_iv16); + &rx->tkip.iv32, + &rx->tkip.iv16); if (res != TKIP_DECRYPT_OK) return RX_DROP_UNUSABLE; @@ -548,6 +548,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, } memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); + if (unlikely(ieee80211_is_frag(hdr))) + memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); } /* Remove CCMP header and MIC */ @@ -777,6 +779,8 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) } memcpy(key->u.gcmp.rx_pn[queue], pn, IEEE80211_GCMP_PN_LEN); + if (unlikely(ieee80211_is_frag(hdr))) + memcpy(rx->ccm_gcm.pn, pn, IEEE80211_CCMP_PN_LEN); } /* Remove GCMP header and MIC */ -- 2.31.1