From nobody Tue Mar 15 18:16:12 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 60B1F1A249FC; Tue, 15 Mar 2022 18:16:13 +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 4KJ1n86SByz58fD; Tue, 15 Mar 2022 18:16:12 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647368173; 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=XpdXqEP0Wp5uS2boOMZHjtkPPeD82YmfvAWttS8jon0=; b=IXI2OnI2SWwUm21UbcFX1fpMrFlGuV6PZWiyjIQGRRLA0ccbegBP6ASzQl0AW4uuzv5+5o AvL7rv8cFZgcQgyoorvxkw6nQms9SpAtTKebe/3/AmhPktant8o8XuhTTTSnz/6KZnTHDT CtJLz66ITEUU89kx5By8BNMQ05Rh5uznlTAr7UMaPZyKiXRu8M+yb72m1GcQ1tfTtdq29c nzCE30mYmwdNMkTU2yL6jEpOveK75TaD1zijZ/JHOvlKXksB5vzIihRLIdH/IvUJlkPhV6 0Q95Zb6b0IZ0ACGuM12IoidSp8z8MOl8Cg15+5rR1BQ5uTC8IXQ6q8C+F4DrDw== 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 B9CCC26A92; Tue, 15 Mar 2022 18:16:12 +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 22FIGCfY075567; Tue, 15 Mar 2022 18:16:12 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22FIGCPg075566; Tue, 15 Mar 2022 18:16:12 GMT (envelope-from git) Date: Tue, 15 Mar 2022 18:16:12 GMT Message-Id: <202203151816.22FIGCPg075566@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 5616c3920f8a - releng/12.3 - net80211: mitigation against A-MSDU design flaw 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: markj X-Git-Repository: src X-Git-Refname: refs/heads/releng/12.3 X-Git-Reftype: branch X-Git-Commit: 5616c3920f8a6a5792f23c1975780f4b54888aa1 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1647368173; 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=XpdXqEP0Wp5uS2boOMZHjtkPPeD82YmfvAWttS8jon0=; b=vt1SDrt1Elg4ejlymZ/Wk63kWdqclImGgjLOdTEVpn526Gsbz9cE4zVVa1oG4+ktorYWHs wzwKRhq/mYl/Bh2iZ+n6M3uTA+HFIX5Ahu4Itb+ZKjWdbuKI57Q7428CJtxs+90hBIJ4eu 6ytRC8U53tEwntWLobosGomxZ4KlOhAax3rtfEu75kBjOHTi5fxPQhpnOSS+qXPJRKg+tV G/WBMAtldiH6YhAU21OgesVw6QpYZwE6Lb32Xab0L1kku6ep6BHsdsn6pZ6+vyOJCnFBes 4cwdnvQG7vM9EaRRRHBo1vYmfGtj5iw1q9NQqikbXXyVlgHdCzqbM6izxmAsDg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1647368173; a=rsa-sha256; cv=none; b=HLyuUcsZ7UOvFNOlv7d+yZDs3/zhiHb1wpLlq5hlCwLJEsEwpthR66PMiNqBTMs4QjDae2 1u4MioJwuSfryFLzGR+cWJd6kmQBP5+Il84UAWBIvC9e7YL1zrs2zrucrB+ty4nTbioa91 RegZ7XBXDoODkoRUfnD8b9GzVnqwE+Xnw6qj722RumPLtzwRGxZf/dVQsKO3J3r1OPTeXu uyFYytjyiswmhA1YGGN6YHw/hKgHHzV8NpYwgdFR6hcbvR7Oq0bd7Zy8Yrdp6EIr0KHkFM rvBod55ZaKyDeiVcY6pDUmNWdNC0qFQuVG6CWYvWSEUIsf3ZZfGCVs/jPdYArQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch releng/12.3 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=5616c3920f8a6a5792f23c1975780f4b54888aa1 commit 5616c3920f8a6a5792f23c1975780f4b54888aa1 Author: Mathy Vanhoef AuthorDate: 2021-06-06 22:10:52 +0000 Commit: Mark Johnston CommitDate: 2022-03-15 17:47:01 +0000 net80211: mitigation against A-MSDU design flaw Mitigate A-MSDU injection attacks by detecting if the destination address of a subframe equals an RFC1042 (i.e., LLC/SNAP) header, and if so dropping the complete A-MSDU frame. This mitigates known attacks, although new (unknown) aggregation-based attacks may remain possible. This defense works because in A-MSDU aggregation injection attacks, a normal encrypted Wi-Fi frame is turned into an A-MSDU frame. This means the first 6 bytes of the first A-MSDU subframe correspond to an RFC1042 header. In other words, the destination MAC address of the first A-MSDU subframe contains the start of an RFC1042 header during an aggregation attack. We can detect this and thereby prevent this specific attack. This relates to section 7.2 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-24588 PR: 256119 (cherry picked from commit f024bdf1155f36d2d8c4caa533b66e4040c4c469) (cherry picked from commit 41ca1d50a8657959df2009daa300dda56a090d5e) (cherry picked from commit 76ee776f4d9f146f7a97ac9bab388c51a1c787c9) Approved by: so Security: FreeBSD-SA-22:02.wifi --- sys/net80211/ieee80211_adhoc.c | 2 +- sys/net80211/ieee80211_hostap.c | 2 +- sys/net80211/ieee80211_input.c | 20 ++++++++++++++++++-- sys/net80211/ieee80211_input.h | 3 ++- sys/net80211/ieee80211_sta.c | 2 +- sys/net80211/ieee80211_wds.c | 2 +- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c index ea1519b3381d..c97b99425caa 100644 --- a/sys/net80211/ieee80211_adhoc.c +++ b/sys/net80211/ieee80211_adhoc.c @@ -558,7 +558,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, /* * Finally, strip the 802.11 header. */ - m = ieee80211_decap(vap, m, hdrspace); + m = ieee80211_decap(vap, m, hdrspace, qos); if (m == NULL) { /* XXX mask bit to check for both */ /* don't count Null data frames as errors */ diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 6687276d0181..8c132332f86b 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -744,7 +744,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, /* * Finally, strip the 802.11 header. */ - m = ieee80211_decap(vap, m, hdrspace); + m = ieee80211_decap(vap, m, hdrspace, qos); if (m == NULL) { /* XXX mask bit to check for both */ /* don't count Null data frames as errors */ diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 404eaf96716a..979e9aef9d12 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -294,7 +294,8 @@ ieee80211_deliver_data(struct ieee80211vap *vap, } struct mbuf * -ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen) +ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen, + uint8_t qos) { struct ieee80211_qosframe_addr4 wh; struct ether_header *eh; @@ -316,7 +317,9 @@ ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen) llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && /* NB: preserve AppleTalk frames that have a native SNAP hdr */ !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || - llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) { + llc->llc_snap.ether_type == htons(ETHERTYPE_IPX)) && + /* Do not want to touch A-MSDU frames. */ + !(qos & IEEE80211_QOS_AMSDU)) { m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); llc = NULL; } else { @@ -364,6 +367,10 @@ ieee80211_decap1(struct mbuf *m, int *framelen) #define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) struct ether_header *eh; struct llc *llc; + const uint8_t llc_hdr_mac[ETHER_ADDR_LEN] = { + /* MAC address matching the 802.2 LLC header */ + LLC_SNAP_LSAP, LLC_SNAP_LSAP, LLC_UI, 0, 0, 0 + }; /* * The frame has an 802.3 header followed by an 802.2 @@ -376,6 +383,15 @@ ieee80211_decap1(struct mbuf *m, int *framelen) if (m->m_len < FF_LLC_SIZE && (m = m_pullup(m, FF_LLC_SIZE)) == NULL) return NULL; eh = mtod(m, struct ether_header *); /* 802.3 header is first */ + + /* + * Detect possible attack where a single 802.11 frame is processed + * as an A-MSDU frame due to an adversary setting the A-MSDU present + * bit in the 802.11 QoS header. [FragAttacks] + */ + if (memcmp(eh->ether_dhost, llc_hdr_mac, ETHER_ADDR_LEN) == 0) + return NULL; + llc = (struct llc *)&eh[1]; /* 802.2 header follows */ *framelen = ntohs(eh->ether_type) /* encap'd frame size */ + sizeof(struct ether_header) - sizeof(struct llc); diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h index 810dcbde7978..5959319c76d7 100644 --- a/sys/net80211/ieee80211_input.h +++ b/sys/net80211/ieee80211_input.h @@ -311,7 +311,8 @@ void ieee80211_deliver_data(struct ieee80211vap *, struct mbuf *ieee80211_defrag(struct ieee80211_node *, struct mbuf *, int); struct mbuf *ieee80211_realign(struct ieee80211vap *, struct mbuf *, size_t); -struct mbuf *ieee80211_decap(struct ieee80211vap *, struct mbuf *, int); +struct mbuf *ieee80211_decap(struct ieee80211vap *, struct mbuf *, int, + uint8_t); struct mbuf *ieee80211_decap1(struct mbuf *, int *); int ieee80211_setup_rates(struct ieee80211_node *ni, const uint8_t *rates, const uint8_t *xrates, int flags); diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 75f6c652c0fb..56372543a200 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -827,7 +827,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, /* * Finally, strip the 802.11 header. */ - m = ieee80211_decap(vap, m, hdrspace); + m = ieee80211_decap(vap, m, hdrspace, qos); if (m == NULL) { /* XXX mask bit to check for both */ /* don't count Null data frames as errors */ diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c index ea13572cf2d9..74cc764b856e 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -619,7 +619,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, /* * Finally, strip the 802.11 header. */ - m = ieee80211_decap(vap, m, hdrspace); + m = ieee80211_decap(vap, m, hdrspace, qos); if (m == NULL) { /* XXX mask bit to check for both */ /* don't count Null data frames as errors */