From: Tristan Madani __rtw89_wow_parse_akm() computes a pointer to the IE area with ies = mgmt->u.assoc_req.variable; and then passes skb->len as the IE data length to cfg80211_find_ie(): rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len); skb->len is the total frame length, not the length of the IE portion. The IEs in an association request start at offset 28 (24-byte header + 4-byte fixed fields), so the correct IE length is skb->len minus that offset. Passing the full frame length causes cfg80211_find_ie() to walk up to 28 bytes past the end of the skb data buffer, triggering a slab-out-of-bounds read. Fix by validating the minimum frame length and passing the correct IE data length to cfg80211_find_ie(). Fixes: 480dd4dddfc5 ("wifi: rtw89: enter power save mode aggressively") Cc: stable@vger.kernel.org Signed-off-by: Tristan Madani --- drivers/net/wireless/realtek/rtw89/wow.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 8dadd8df4fc65..82b74ded68631 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -16,10 +16,16 @@ void __rtw89_wow_parse_akm(struct rtw89_dev *rtwdev, struct sk_buff *skb) { struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; struct rtw89_wow_param *rtw_wow = &rtwdev->wow; + size_t hdr_len = offsetof(struct ieee80211_mgmt, u.assoc_req.variable); const u8 *rsn, *ies = mgmt->u.assoc_req.variable; struct rtw89_rsn_ie *rsn_ie; - rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, skb->len); + if (skb->len < hdr_len) + return; + + rsn = cfg80211_find_ie(WLAN_EID_RSN, ies, + skb->len - hdr_len); + if (!rsn) return; -- 2.47.3