From nobody Tue Feb 15 16:04:19 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 CDC2319B9B24; Tue, 15 Feb 2022 16:04:19 +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 4Jym9v52jrz3qbx; Tue, 15 Feb 2022 16:04:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1644941059; 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=UgyvEU7Bs1agZ1dHENCHTzydOCwT1Xc4TaTtn7k22Ps=; b=PJ8VUblxwmTPRZvDX9B6+L4xc89Xsi2d6fYzHe0PaO0qc+iy5pnuq7FW7pp4nRsEi0lf/i eLad9TlS3O2YfFGkSia0MAPdYHQzaIMQXASF6c8S90yBk8/k6DXtvDDJD8kpJlsfGSVHsv yuGvCjNAVqrd81qEwzPtMwGYLde3q085fb/RjXE56Cxua8pbiFrXQwOTEdU+reMOxZb6yK BpVlDRJECe1shQkFDIAMT9Z4+pLluLEZdBjxR3ZrsduNLa6LDPJ4BNLN+1n05QB2GDEc7d w5Cp01+kvvjGIsNSlbLjLgRaASJVoeMLiz7zFmXJkmKkeKzoYc7M048sjc9zhg== 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 8D3622505D; Tue, 15 Feb 2022 16:04:19 +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 21FG4JUN072129; Tue, 15 Feb 2022 16:04:19 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 21FG4Jeu072127; Tue, 15 Feb 2022 16:04:19 GMT (envelope-from git) Date: Tue, 15 Feb 2022 16:04:19 GMT Message-Id: <202202151604.21FG4Jeu072127@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: 2d09e4366b67 - stable/12 - net80211: prevent plaintext injection by A-MSDU RFC1042/EAPOL frames List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: 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: emaste X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: 2d09e4366b67dd719ebae5390436868e5430d833 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1644941059; 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=UgyvEU7Bs1agZ1dHENCHTzydOCwT1Xc4TaTtn7k22Ps=; b=ks7A3dfwCNOE+/vFtjGrXTkIs0lnqftYYm7InZcP917cZoKj27NJAq3T9Ffxs4z6VTCx21 4wUZlvorTSPXkwJFVhKgbrUnLrVUMa0kIK/qBp9gGSROEvpn9gTwqYMvgrrZMY/bU0U/mA 8FLPG6jR59uEUCOPeGziABmfOsVhTdwyLXhuRmIXCHPh8AixV59TOrLJsknR/RkY6E9W3r E8qtNCT7CTGI6x/OKcucbYCALZoh06YtARtcp+mo/FbjWmuizyke+CiXuxqRLNVFqomSN6 01ynKGifhQxmtC5nj4aaSdMyFTZCoviHPjP6XLtQg4/I5067wmITLb2DlCW7Hw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1644941059; a=rsa-sha256; cv=none; b=mCpf2gooR0edUh36dT9KjAWZbBMcat+fLJfJ7c3aTR+K69hIpqkuT3V1w93EJddBZLaVSt NBsI9wtRSHFNu4XB6aKWiMp6EcHvUg+oorAI+Jbm0OF0CuORBGPpGB9TPSnCiDw2rq/ctg uR/En0DjkEw2TOhaZ6Hx62CP4AjtEiE76ke6ql/hjw1xME2xTdVKbVw0zBqhS8zIt0J13l fIEhZXFb+RWCCBBbU5SF1a9CZ9zasarQCXQ0AIjwtt+bKEw+oZTBxgdY1C5lMUOMw4nCBk f73YferwBKn954m/Adm9MhdemKhk9EaIe5IVkTOH1pTF/7cJ9NckkzzNHozcRA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/12 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=2d09e4366b67dd719ebae5390436868e5430d833 commit 2d09e4366b67dd719ebae5390436868e5430d833 Author: Mathy Vanhoef AuthorDate: 2021-06-06 22:10:56 +0000 Commit: Ed Maste CommitDate: 2022-02-15 15:03:09 +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) --- 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 8183d3e9b25a..3f86fd785a91 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 42a377f12857..18177f85d758 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 dc0d9f8e1afd..e479cee5ddde 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -632,7 +632,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 @@ -642,11 +645,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; @@ -659,7 +664,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. */