Commit e298aa35 authored by Du Cheng's avatar Du Cheng Committed by Johannes Berg
Browse files

mac80211: fix skb length check in ieee80211_scan_rx()



Replace hard-coded compile-time constants for header length check
with dynamic determination based on the frame type. Otherwise, we
hit a validation WARN_ON in cfg80211 later.

Fixes: cd418ba6 ("mac80211: convert S1G beacon to scan results")
Reported-by: default avatar <syzbot+405843667e93b9790fc1@syzkaller.appspotmail.com>
Signed-off-by: default avatarDu Cheng <ducheng2@gmail.com>
Link: https://lore.kernel.org/r/20210510041649.589754-1-ducheng2@gmail.com


[style fixes, reword commit message]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent b90f51e8
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -251,13 +251,24 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
	struct ieee80211_mgmt *mgmt = (void *)skb->data;
	struct ieee80211_bss *bss;
	struct ieee80211_channel *channel;
	size_t min_hdr_len = offsetof(struct ieee80211_mgmt,
				      u.probe_resp.variable);

	if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
		if (skb->len < 15)
	if (!ieee80211_is_probe_resp(mgmt->frame_control) &&
	    !ieee80211_is_beacon(mgmt->frame_control) &&
	    !ieee80211_is_s1g_beacon(mgmt->frame_control))
		return;
	} else if (skb->len < 24 ||
		 (!ieee80211_is_probe_resp(mgmt->frame_control) &&
		  !ieee80211_is_beacon(mgmt->frame_control)))

	if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
		if (ieee80211_is_s1g_short_beacon(mgmt->frame_control))
			min_hdr_len = offsetof(struct ieee80211_ext,
					       u.s1g_short_beacon.variable);
		else
			min_hdr_len = offsetof(struct ieee80211_ext,
					       u.s1g_beacon);
	}

	if (skb->len < min_hdr_len)
		return;

	sdata1 = rcu_dereference(local->scan_sdata);