Page MenuHomeFreeBSD

D30664.diff
No OneTemporary

D30664.diff

diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -558,7 +558,7 @@
/*
* 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
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -744,7 +744,7 @@
/*
* 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.h b/sys/net80211/ieee80211_input.h
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -311,7 +311,8 @@
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_input.c b/sys/net80211/ieee80211_input.c
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -309,7 +309,8 @@
}
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;
@@ -331,7 +332,9 @@
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 {
@@ -379,6 +382,10 @@
#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
@@ -391,6 +398,15 @@
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_sta.c b/sys/net80211/ieee80211_sta.c
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -827,7 +827,7 @@
/*
* 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
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -621,7 +621,7 @@
/*
* 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 */

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 24, 3:56 AM (4 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24117415
Default Alt Text
D30664.diff (4 KB)

Event Timeline