In ieee80211_rx_h_defragment(), fragment payloads are accumulated into
entry->extra_len as subsequent fragments arrive:
entry->extra_len += rx->skb->len;
When the final fragment arrives, the head fragment is dequeued, and
pskb_expand_head() is called with entry->extra_len to ensure sufficient
tailroom for all queued fragments before copying:
if (skb_tailroom(rx->skb) < entry->extra_len) {
if (unlikely(pskb_expand_head(rx->skb, 0, entry->extra_len,
GFP_ATOMIC))) {
...
}
}
while ((skb = __skb_dequeue(&entry->skb_list))) {
skb_put_data(rx->skb, skb->data, skb->len);
dev_kfree_skb(skb);
}
In commit 69f1322368 ("mac80211: shrink struct
ieee80211_fragment_entry"), entry->extra_len was narrowed from unsigned
int to u16 in order to reduce structure memory footprint.
However, an IEEE 802.11 frame sequence can contain up to 16 fragments
(frag numbers 0..15). If a sequence of large fragments arrives (e.g. from
a malicious peer or rogue AP), the sum of fragment lengths can exceed
65535 bytes (for example, 15 fragments of 4400 bytes total 66000 bytes).
Because extra_len is a u16, this addition overflows and wraps around
modulo 65536 (e.g. 66000 wraps to 464).
Consequently, pskb_expand_head() allocates only the truncated amount of
tailroom (or is skipped entirely if the head fragment already has >= 464
bytes of tailroom). When skb_put_data() subsequently iterates through the
queued skb list, it appends the full payload into the undersized buffer,
causing skb_put() to trigger skb_over_panic() and crash the kernel in
softirq context.
A legitimate MSDU in IEEE 802.11 is at most 2304 bytes (or up to 7935/11454
bytes for A-MSDU, which is not fragmented), well below U16_MAX.
Fix this without increasing the size of struct ieee80211_fragment_entry by
checking whether adding the incoming fragment length would exceed U16_MAX.
If so, purge the queued fragments and drop the frame.
Fixes: 69f1322368 ("mac80211: shrink struct ieee80211_fragment_entry")
Signed-off-by: Yuchao Zhang <ndaugoing@gmail.com>
Link: https://patch.msgid.link/20260918034004.85078-2-ndaugoing@gmail.com
[assign a separate drop reason]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Hostapd switched from cooked monitor interfaces to nl80211 Dec 2011.
Drop support for the outdated cooked monitor interfaces and fix
creating the virtual monitor interfaces in the following cases:
1) We have one non-monitor and one monitor interface with
%MONITOR_FLAG_ACTIVE enabled and then delete the non-monitor
interface.
2) We only have monitor interfaces enabled on resume while at least one
has %MONITOR_FLAG_ACTIVE set.
Signed-off-by: Alexander Wetzel <Alexander@wetzel-home.de>
Link: https://patch.msgid.link/20250204111352.7004-2-Alexander@wetzel-home.de
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
If we use a drop we not only save the extra call to
dev_kfree_skb(), but also have a better reason in
tracing, so do that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240320091155.34daf0a89eb4.I60e0639511f9de64e40e6105b640adf90f8f57f7@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Make __ieee80211_data_to_8023() return more individual drop
reasons instead of just doing RX_DROP_U_INVALID_8023.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This has many different reasons, split the return value into
the individual reasons for better traceability. Also, since
symbolic tracing doesn't work for these, add a few comments
for the numbering.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Convert all instances of RX_DROP_UNUSABLE to indicate a
better reason, and then remove RX_DROP_UNUSABLE.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
If we just check "result & RX_DROP_UNUSABLE", this really only works
by accident, because SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE got to
have the value 1, and SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR is 2.
Fix this to really check the entire subsys mask for the value, so it
doesn't matter what the subsystem value is.
Fixes: 7f4e09700b ("wifi: mac80211: report all unusable beacon frames")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
It can be really hard to analyse or debug why packets are
going missing in mac80211, so add the needed infrastructure
to use use the new per-subsystem drop reasons.
We actually use two drop reason subsystems here because of
the different handling of frames that are dropped but still
go to monitor for old versions of hostapd, and those that
are just completely unusable (e.g. crypto failed.)
Annotate a few reasons here just to illustrate this, we'll
need to go through and annotate more of them later.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>