FreeBSD Bugzilla – Attachment 225221 Details for
Bug 256119
[net80211] [patch]: mitigate A-MSDU FragAttacks design flaw
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
patch: git diff file
0002-net80211-mitigation-against-A-MSDU-design-flaw.patch (text/plain), 6.27 KB, created by
Mathy
on 2021-05-24 13:16:55 UTC
(
hide
)
Description:
patch: git diff file
Filename:
MIME Type:
Creator:
Mathy
Created:
2021-05-24 13:16:55 UTC
Size:
6.27 KB
patch
obsolete
>From ed02e3a5036fd0d127a71f8cd7ef18d0106a9cc4 Mon Sep 17 00:00:00 2001 >From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be> >Date: Mon, 24 May 2021 15:23:58 +0400 >Subject: [PATCH 2/3] net80211: mitigation against A-MSDU design flaw > >Mitigate A-MSDU injection attacks (CVE-2020-24588) 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. >For details, see Section 7.2 of "Fragment and Forge: Breaking Wi-Fi >Through Frame Aggregation and Fragmentation". >--- > sys/net80211/ieee80211_adhoc.c | 2 +- > sys/net80211/ieee80211_hostap.c | 2 +- > sys/net80211/ieee80211_input.c | 21 +++++++++++++++++++-- > sys/net80211/ieee80211_input.h | 3 ++- > sys/net80211/ieee80211_sta.c | 2 +- > sys/net80211/ieee80211_wds.c | 2 +- > 6 files changed, 25 insertions(+), 7 deletions(-) > >diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c >index a23f138802d..e2164bbb46a 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 15d42a68235..75fa1c0f7b3 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 9e2189c7e43..f405a99410c 100644 >--- a/sys/net80211/ieee80211_input.c >+++ b/sys/net80211/ieee80211_input.c >@@ -308,7 +308,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; >@@ -330,7 +331,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)) && >+ /* don't want to touch A-MSDU frames */ >+ !(qos & IEEE80211_QOS_AMSDU)) { > m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); > llc = NULL; > } else { >@@ -378,6 +381,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 >@@ -390,6 +397,16 @@ 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. See Section 7.2 of the paper >+ * https://papers.mathyvanhoef.com/usenix2021.pdf >+ */ >+ if (memcmp(eh->ether_dhost, llc_hdr_mac, 6) == 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 8ec82eef736..ae2b4644cc9 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, 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 6d24eadc11a..60a5ea10055 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 f59a92b992d..f88871ca4ae 100644 >--- a/sys/net80211/ieee80211_wds.c >+++ b/sys/net80211/ieee80211_wds.c >@@ -621,7 +621,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 */ >-- >2.31.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 256119
: 225221