From: Ping-Ke Shih Date: Tue, 14 Apr 2026 06:22:28 +0000 (+0800) Subject: wifi: rtlwifi: validate action frame size in rtl_action_proc() X-Git-Tag: v7.2-rc1~143^2~94^2~24^2~100 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c9f10419c38ed619fadad7b8d72f05fca5b4ade8;p=thirdparty%2Fkernel%2Flinux.git wifi: rtlwifi: validate action frame size in rtl_action_proc() Since action frames might be malformed from RX or injected TX, validate the size before using. More, use struct ieee80211_mgmt to access fields of action frames instead of counting barely. Tested with ping on RTL8723BE. The add BA request action frames of TX/RX can be handled properly. Signed-off-by: Ping-Ke Shih Link: https://patch.msgid.link/20260414062229.21047-3-pkshih@realtek.com --- diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index aad377864e73b..9e98c01bb90e6 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -1369,18 +1369,19 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct ieee80211_hdr *hdr = rtl_get_hdr(skb); struct rtl_priv *rtlpriv = rtl_priv(hw); + struct ieee80211_mgmt *mgmt; __le16 fc = rtl_get_fc(skb); - u8 *act = (u8 *)(((u8 *)skb->data + MAC80211_3ADDR_LEN)); - u8 category; if (!ieee80211_is_action(fc)) return true; - category = *act; - act++; - switch (category) { + mgmt = (void *)skb->data; + if (skb->len < IEEE80211_MIN_ACTION_SIZE(action_code)) + return true; + + switch (mgmt->u.action.category) { case ACT_CAT_BA: - switch (*act) { + switch (mgmt->u.action.action_code) { case ACT_ADDBAREQ: if (mac->act_scanning) return false; @@ -1394,9 +1395,11 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) struct ieee80211_sta *sta = NULL; struct rtl_sta_info *sta_entry = NULL; struct rtl_tid_data *tid_data; - struct ieee80211_mgmt *mgmt = (void *)skb->data; u16 capab = 0, tid = 0; + if (skb->len < IEEE80211_MIN_ACTION_SIZE(addba_req)) + return true; + rcu_read_lock(); sta = rtl_find_sta(hw, hdr->addr3); if (sta == NULL) {