mwifiex_process_multi_chan_event() reads chan_info->header.type at event_skb->data + 4 before checking that the event is long enough to hold it, and computes the remaining TLV space as tlv_buf_left = event_skb->len - sizeof(u32); where tlv_buf_left is a u16. When event_skb->len is smaller than 4, tlv_buf_left wraps to a large value, so the subsequent minimum-length check fails to reject the event. If the TLV type matches, parsing continues beyond the valid event data. The EVENT_MULTI_CHAN_INFO cases in sta_event.c and uap_event.c call this handler without checking event_skb->len. Check event_skb->len against the fixed part of the event before touching chan_info. Fixes: 8d6b538a5eac ("mwifiex: handle multichannel event") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Huihui Huang --- drivers/net/wireless/marvell/mwifiex/sta_event.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) Tested on Linux v7.3-rc7 (wireless.git main) with a temporary handler-level KUnit regression test (UML). The test allocates a 64-byte skb, writes a 4-byte event cause followed by a multi-channel TLV (type TLV_TYPE_MULTI_CHAN_INFO, status 1), but skb_put()s only 2 bytes, so the handler is called with skb->len == 2. Verbatim KUnit output: before this change: # mwifiex_multi_chan_short_event_test: skb->len=2 usb_mc_status=1 (want 0) not ok 1 mwifiex_multi_chan_short_event_test after this change: # mwifiex_multi_chan_short_event_test: skb->len=2 usb_mc_status=0 (want 0) ok 1 mwifiex_multi_chan_short_event_test Before this change the handler parses bytes beyond skb->len and sets adapter->usb_mc_status from them; after it the event is rejected. base-commit: 25e73f1d6868c759c8eb56cad4e411692c5341b4 diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index fecd88967ceb..a9e74f589e4c 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -419,8 +419,9 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv, tlv_buf_left = event_skb->len - sizeof(u32); chan_info = (void *)event_skb->data + sizeof(u32); - if (le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO || - tlv_buf_left < sizeof(struct mwifiex_ie_types_multi_chan_info)) { + if (event_skb->len < sizeof(u32) + + sizeof(struct mwifiex_ie_types_multi_chan_info) || + le16_to_cpu(chan_info->header.type) != TLV_TYPE_MULTI_CHAN_INFO) { mwifiex_dbg(adapter, ERROR, "unknown TLV in chan_info event\n"); return; -- 2.43.0