Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp2883233pxj; Mon, 31 May 2021 13:34:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxVzsousUAOe8CguhkOKKqAv2aiuJ1ohzf/A34LJ+Uw7Btt9d6FxGWcqyb4NFfttwxBRnpK X-Received: by 2002:a17:906:5495:: with SMTP id r21mr25138897ejo.471.1622493291891; Mon, 31 May 2021 13:34:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1622493291; cv=none; d=google.com; s=arc-20160816; b=f1Xldm4/TE2VehBHubIkWFiEVAx71V1/399wEh8AAEREJghT3TPoI1aa3U3qEBbTcb lMFhfa2sr4ku5V41LhdrmcmUw2in2nmgnBvqwHo2vWwOnr1fzme9edcRbxaXslvDUaEN XmHh+z7Aq/DTbZBvh82GESf5hAXxzCeCgWKvbv+BfGvBZ2bWa/6HSTQyEca2sfM4P+xc IMyYHmVySB5YfgpsqGsRSRNFkQEeJA/uJigxM6nqKxvV0r/tR5d+APcDgmW4kfzL5Upz ysbJR1TFOWJJrooprXYznzVfw4f7b5/s1kZKskKklbp3C3u2xxuokfFNX5Op8T+33Dli kxRQ== 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=iI2z0Qpq0SPfVus1C9aQQ+jNKk52t2HVYomI9LdwsfA=; b=drIZK1Zy70R9VkAZUUznBH4NeTK/n4u3LYvQENKzl77viOri+dMGx3cMD8n1qaXJVq b27JXXJLSZnhCW3AvS61Ntr/stfI7M6dZhZVMIBEe7O8Yi8cIJXw32z5Epu6yDO+SuqI tJChoii9HeIggipM9zLdZVygeeklxfeE2cO979CSZqGwuzkhdWzBGwRlmsMbOJ/PPWOX KWPu3LkRRLsJ5JXqqi7IFGL3XUDvEPsRCwk2h6G6+OuS2qTQFVZ6M41OvcaSq5Gr5YI7 dh2JQ+OX77r0Ef/cXkou723wBFyVfPWPtFCIdXw7nU8iz5zbcZx0Jz539ta2MfRRndDR wBzA== 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 u7si3481830eds.594.2021.05.31.13.34.23; Mon, 31 May 2021 13:34:51 -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 S232539AbhEaUdw (ORCPT + 99 others); Mon, 31 May 2021 16:33:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232455AbhEaUdX (ORCPT ); Mon, 31 May 2021 16:33:23 -0400 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:191:4433::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A5FAC061763; Mon, 31 May 2021 13:31:42 -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 1lnoZY-000FBv-D6; Mon, 31 May 2021 22:31:40 +0200 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: stable@vger.kernel.org, Johannes Berg Subject: [PATCH v4.14 07/10] mac80211: check defrag PN against current frame Date: Mon, 31 May 2021 22:31:32 +0200 Message-Id: <20210531203135.180427-8-johannes@sipsolutions.net> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210531203135.180427-1-johannes@sipsolutions.net> References: <20210531203135.180427-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 f38748efb98a..790c771e8108 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -223,8 +223,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 39bc3d78f71a..a00ec2ccb363 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2082,7 +2082,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; @@ -2097,8 +2096,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 e3bb69ba6887..09b4f913e20b 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