From nobody Tue Mar 15 18:14:05 2022
X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1])
	by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 796CA1A22C47;
	Tue, 15 Mar 2022 18:14:06 +0000 (UTC)
	(envelope-from git@FreeBSD.org)
Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256
	 client-signature RSA-PSS (4096 bits) client-digest SHA256)
	(Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK))
	by mx1.freebsd.org (Postfix) with ESMTPS id 4KJ1kk1D4lz57TQ;
	Tue, 15 Mar 2022 18:14:06 +0000 (UTC)
	(envelope-from git@FreeBSD.org)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim;
	t=1647368046;
	h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
	 to:to:cc:mime-version:mime-version:content-type:content-type:
	 content-transfer-encoding:content-transfer-encoding;
	bh=tCiFi2PjIbzANQm3bK1kWcYGrlamvcNejVfmbC/M/kM=;
	b=Db7myt40PrKUtLtrX3uKMWYnY1Bx/40rLhPzmyzD8jXPKhbTG+Ezauh/OQy32qTK/E4SZ8
	MLX7vs7gsRTMAJ4UGg/1QuSJcZs+vJ8FZwqIAwKi1KQ78zBP2RdP7mxCw7MxEgOyXjfOoH
	+4Gjjp0ExGIgVubIZQrM3l2fTrnCzq3ixWLYDtm98Gh0b36I8z04m7/k8U9rhVn8RyBsK9
	VWYYZijx2uCDwueCjYLd6v+h8qZbcds+zBkYnTMSFwPleqANcX/sVtMMYziBLJGydWH8PQ
	Y6ZJuT69kWQ4yuH8MRjp8jjdDyipdm4ugIIca2mDlY16MpEu3auId6wIC/3IXQ==
Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256)
	(Client did not present a certificate)
	by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id EB80326B8D;
	Tue, 15 Mar 2022 18:14:05 +0000 (UTC)
	(envelope-from git@FreeBSD.org)
Received: from gitrepo.freebsd.org ([127.0.1.44])
	by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 22FIE5R1074951;
	Tue, 15 Mar 2022 18:14:05 GMT
	(envelope-from git@gitrepo.freebsd.org)
Received: (from git@localhost)
	by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22FIE5Ym074950;
	Tue, 15 Mar 2022 18:14:05 GMT
	(envelope-from git)
Date: Tue, 15 Mar 2022 18:14:05 GMT
Message-Id: <202203151814.22FIE5Ym074950@gitrepo.freebsd.org>
To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org,
        dev-commits-src-branches@FreeBSD.org
From: Mark Johnston <markj@FreeBSD.org>
Subject: git: cbfb77f1953b - releng/13.0 - net80211: prevent plaintext injection by A-MSDU RFC1042/EAPOL frames
List-Id: Commit messages for all branches of the src repository <dev-commits-src-all.freebsd.org>
List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all
List-Help: <mailto:dev-commits-src-all+help@freebsd.org>
List-Post: <mailto:dev-commits-src-all@freebsd.org>
List-Subscribe: <mailto:dev-commits-src-all+subscribe@freebsd.org>
List-Unsubscribe: <mailto:dev-commits-src-all+unsubscribe@freebsd.org>
Sender: owner-dev-commits-src-all@freebsd.org
X-BeenThere: dev-commits-src-all@freebsd.org
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
X-Git-Committer: markj
X-Git-Repository: src
X-Git-Refname: refs/heads/releng/13.0
X-Git-Reftype: branch
X-Git-Commit: cbfb77f1953bde3c4d23bf2278e2762053d80fe9
Auto-Submitted: auto-generated
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org;
	s=dkim; t=1647368046;
	h=from:from:reply-to:subject:subject:date:date:message-id:message-id:
	 to:to:cc:mime-version:mime-version:content-type:content-type:
	 content-transfer-encoding:content-transfer-encoding;
	bh=tCiFi2PjIbzANQm3bK1kWcYGrlamvcNejVfmbC/M/kM=;
	b=QmWr9PuZ6hWDcx1cpirU+QrYeib5TjHMZQOH7ACA+KqA+6mRReFuzIqhsjiQkAE1tQU/cL
	05qsS0DXRCiC1Dyjddu7Y4z2pamaQ5/ZUlyg258KUSFe3i0sGxLSCGR3oaP8yXmtAPNJwG
	tu8KozN3et28r6Xc9sGxAyz/Sp/4UqCHxqSH2Jv3spYv1xA8XfR5gfGvdShhgJC/JICmgS
	ef5xNivd0kP2D3noD1PVmTPoWEMyDKjPY8PNJ8cAz5gE4QrxH+7lq4R0tweuVOsLCZPZUn
	BQpAGvDBTk1GhbO0MUoCnMOQ9RouAaEYbaiXXvE9cGs00HgL9p4CtBammzZhdQ==
ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1647368046; a=rsa-sha256; cv=none;
	b=s7ttg4sadMnyn/pUt1cj1i+iJ6bFjKs9X1Eo3pV1435ysEsUkByljZJ0TZaUeueQasotKs
	FRjX9CA6vv5pVuxNhR+vbmIDOhDzvqwe/fmGG2xF5Xu8YGMuXpl4yVs4gVaaIHdXNpEw0M
	Wm4M9x/rbO6GGsa1fJJxFYYbckg6+Xka0VP7oK7eoRKYKbmNotX4mhr+QwfGn9/qsrNanQ
	Bh7bu58teowo1rzEv2hfP0+gHL/ZwNzUGJ8TVsDp7RKcGBQ3G4YwMzQ79zflif7uIkhx7K
	TYnIBsJAWBnvS3CJ9kZmy4957cNWjmKq0vr2quFANaJ6/Z74Pv7i//DDe19XVg==
ARC-Authentication-Results: i=1;
	mx1.freebsd.org;
	none
X-ThisMailContainsUnwantedMimeParts: N

The branch releng/13.0 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=cbfb77f1953bde3c4d23bf2278e2762053d80fe9

commit cbfb77f1953bde3c4d23bf2278e2762053d80fe9
Author:     Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
AuthorDate: 2021-06-06 22:10:56 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-03-15 17:45:19 +0000

    net80211: prevent plaintext injection by A-MSDU RFC1042/EAPOL frames
    
    No longer accept plaintext A-MSDU frames that start with an RFC1042
    header with EtherType EAPOL.  This is done by only accepting EAPOL
    packets that are included in non-aggregated 802.11 frames.
    
    Note that before this patch, FreeBSD also only accepted EAPOL frames
    that are sent in a non-aggregated 802.11 frame due to bugs in
    processing EAPOL packets inside A-MSDUs. In other words,
    compatibility with legitimate devices remains the same.
    
    This relates to section 6.5 in the 2021 Usenix "FragAttacks" (Fragment
    and Forge: Breaking Wi-Fi Through Frame Aggregation and Fragmentation)
    paper.
    
    Submitted by:   Mathy Vanhoef (Mathy.Vanhoef kuleuven.be)
    Security:       CVE-2020-26144
    PR:             256120
    
    (cherry picked from commit ffc19cf52da5546973965f78cf32aa0f2c9657f8)
    (cherry picked from commit 8b2ba742cc2c732bc4bc1d43f8256adce06657d0)
    
    Approved by:    so
    Security:       FreeBSD-SA-22:02.wifi
---
 sys/net80211/ieee80211_adhoc.c  | 18 ++++++++++++------
 sys/net80211/ieee80211_hostap.c | 18 ++++++++++++------
 sys/net80211/ieee80211_sta.c    | 18 ++++++++++++------
 sys/net80211/ieee80211_wds.c    | 18 ++++++++++++------
 4 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index e2164bbb46a1..150515222268 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -571,7 +571,10 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
 			IEEE80211_NODE_STAT(ni, rx_decap);
 			goto err;
 		}
-		eh = mtod(m, struct ether_header *);
+		if (!(qos & IEEE80211_QOS_AMSDU))
+			eh = mtod(m, struct ether_header *);
+		else
+			eh = NULL;
 		if (!ieee80211_node_is_authorized(ni)) {
 			/*
 			 * Deny any non-PAE frames received prior to
@@ -581,11 +584,13 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
 			 * the port is not marked authorized by the
 			 * authenticator until the handshake has completed.
 			 */
-			if (eh->ether_type != htons(ETHERTYPE_PAE)) {
+			if (eh == NULL ||
+			    eh->ether_type != htons(ETHERTYPE_PAE)) {
 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
-				    eh->ether_shost, "data",
-				    "unauthorized port: ether type 0x%x len %u",
-				    eh->ether_type, m->m_pkthdr.len);
+				    ni->ni_macaddr, "data", "unauthorized or "
+				    "unknown port: ether type 0x%x len %u",
+				    eh == NULL ? -1 : eh->ether_type,
+				    m->m_pkthdr.len);
 				vap->iv_stats.is_rx_unauth++;
 				IEEE80211_NODE_STAT(ni, rx_unauth);
 				goto err;
@@ -598,7 +603,8 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
 			if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
 			    ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) &&
 			    (is_hw_decrypted == 0) &&
-			    eh->ether_type != htons(ETHERTYPE_PAE)) {
+			    (eh == NULL ||
+			     eh->ether_type != htons(ETHERTYPE_PAE))) {
 				/*
 				 * Drop unencrypted frames.
 				 */
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 80e58fd752a7..35dfc30defa9 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -757,7 +757,10 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m,
 			IEEE80211_NODE_STAT(ni, rx_decap);
 			goto err;
 		}
-		eh = mtod(m, struct ether_header *);
+		if (!(qos & IEEE80211_QOS_AMSDU))
+			eh = mtod(m, struct ether_header *);
+		else
+			eh = NULL;
 		if (!ieee80211_node_is_authorized(ni)) {
 			/*
 			 * Deny any non-PAE frames received prior to
@@ -767,11 +770,13 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m,
 			 * the port is not marked authorized by the
 			 * authenticator until the handshake has completed.
 			 */
-			if (eh->ether_type != htons(ETHERTYPE_PAE)) {
+			if (eh == NULL ||
+			    eh->ether_type != htons(ETHERTYPE_PAE)) {
 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
-				    eh->ether_shost, "data",
-				    "unauthorized port: ether type 0x%x len %u",
-				    eh->ether_type, m->m_pkthdr.len);
+				    ni->ni_macaddr, "data", "unauthorized or "
+				    "unknown port: ether type 0x%x len %u",
+				    eh == NULL ? -1 : eh->ether_type,
+				    m->m_pkthdr.len);
 				vap->iv_stats.is_rx_unauth++;
 				IEEE80211_NODE_STAT(ni, rx_unauth);
 				goto err;
@@ -784,7 +789,8 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m,
 			if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
 			    ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) &&
 			    (is_hw_decrypted == 0) &&
-			    eh->ether_type != htons(ETHERTYPE_PAE)) {
+			    (eh == NULL ||
+			     eh->ether_type != htons(ETHERTYPE_PAE))) {
 				/*
 				 * Drop unencrypted frames.
 				 */
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
index 60a5ea100556..cd62266ab942 100644
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -840,7 +840,10 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m,
 			IEEE80211_NODE_STAT(ni, rx_decap);
 			goto err;
 		}
-		eh = mtod(m, struct ether_header *);
+		if (!(qos & IEEE80211_QOS_AMSDU))
+			eh = mtod(m, struct ether_header *);
+		else
+			eh = NULL;
 		if (!ieee80211_node_is_authorized(ni)) {
 			/*
 			 * Deny any non-PAE frames received prior to
@@ -850,11 +853,13 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m,
 			 * the port is not marked authorized by the
 			 * authenticator until the handshake has completed.
 			 */
-			if (eh->ether_type != htons(ETHERTYPE_PAE)) {
+			if (eh == NULL ||
+			    eh->ether_type != htons(ETHERTYPE_PAE)) {
 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
-				    eh->ether_shost, "data",
-				    "unauthorized port: ether type 0x%x len %u",
-				    eh->ether_type, m->m_pkthdr.len);
+				    ni->ni_macaddr, "data", "unauthorized or "
+				    "unknown port: ether type 0x%x len %u",
+				    eh == NULL ? -1 : eh->ether_type,
+				    m->m_pkthdr.len);
 				vap->iv_stats.is_rx_unauth++;
 				IEEE80211_NODE_STAT(ni, rx_unauth);
 				goto err;
@@ -867,7 +872,8 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m,
 			if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
 			    ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) &&
 			    (is_hw_decrypted == 0) &&
-			    eh->ether_type != htons(ETHERTYPE_PAE)) {
+			    (eh == NULL ||
+			     eh->ether_type != htons(ETHERTYPE_PAE))) {
 				/*
 				 * Drop unencrypted frames.
 				 */
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
index f88871ca4ae6..b73988b10d5e 100644
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -634,7 +634,10 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m,
 			IEEE80211_NODE_STAT(ni, rx_decap);
 			goto err;
 		}
-		eh = mtod(m, struct ether_header *);
+		if (!(qos & IEEE80211_QOS_AMSDU))
+			eh = mtod(m, struct ether_header *);
+		else
+			eh = NULL;
 		if (!ieee80211_node_is_authorized(ni)) {
 			/*
 			 * Deny any non-PAE frames received prior to
@@ -644,11 +647,13 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m,
 			 * the port is not marked authorized by the
 			 * authenticator until the handshake has completed.
 			 */
-			if (eh->ether_type != htons(ETHERTYPE_PAE)) {
+			if (eh == NULL ||
+			    eh->ether_type != htons(ETHERTYPE_PAE)) {
 				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
-				    eh->ether_shost, "data",
-				    "unauthorized port: ether type 0x%x len %u",
-				    eh->ether_type, m->m_pkthdr.len);
+				    ni->ni_macaddr, "data", "unauthorized or "
+				    "unknown port: ether type 0x%x len %u",
+				    eh == NULL ? -1 : eh->ether_type,
+				    m->m_pkthdr.len);
 				vap->iv_stats.is_rx_unauth++;
 				IEEE80211_NODE_STAT(ni, rx_unauth);
 				goto err;
@@ -661,7 +666,8 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m,
 			if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
 			    ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) &&
 			    (is_hw_decrypted == 0) &&
-			    eh->ether_type != htons(ETHERTYPE_PAE)) {
+			    (eh == NULL ||
+			     eh->ether_type != htons(ETHERTYPE_PAE))) {
 				/*
 				 * Drop unencrypted frames.
 				 */