mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: Zhao Li <enderaoelyther@gmail.com>
Cc: Thomas Pedersen <thomas@adapt-ip.com>,
	linux-wireless@vger.kernel.org,  linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH] wifi: mac80211: validate S1G beacon length before RX
Date: Thu, 11 Jun 2026 14:03:03 +0200	[thread overview]
Message-ID: <2dbb5e703e5d7fa787c9f0debcedb3dc73c1643d.camel@sipsolutions.net> (raw)
In-Reply-To: <20260610162700.58722-1-enderaoelyther@gmail.com>

On Thu, 2026-06-11 at 00:27 +0800, Zhao Li wrote:
> S1G beacons are extension frames, so ieee80211_hdrlen() only guarantees
> the extension header before the generic RX path starts dispatching the
> frame.
> 
> The RX path can then reach helpers and interface handling code that read
> regular 802.11 header address fields, which are not present at those
> offsets in an S1G beacon.
> 
> Pull the complete S1G beacon fixed header, including optional fixed
> fields indicated by frame control, before generic RX dispatch.
> 
> Also make ieee80211_get_bssid() length-safe for S1G beacons and avoid
> regular-header address reads for S1G frames in accept/interface/MLO
> address handling. Skip extension frames in duplicate detection for the
> same reason, since that path consumes the regular sequence-control field.

This is all true, but all of the below seems far too complicated a fix?

Also seems like you should probably disclose some LLM usage, unless
you're going to tell me you wrote all this code yourself?


> @@ -4487,12 +4490,17 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
>  	struct ieee80211_hdr *hdr = (void *)skb->data;
>  	struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
>  	u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
> -	bool multicast = is_multicast_ether_addr(hdr->addr1) ||
> -			 ieee80211_is_s1g_beacon(hdr->frame_control);
> +	bool s1g = ieee80211_is_s1g_beacon(hdr->frame_control);
> +	bool multicast;
>  	static const u8 nan_network_id[ETH_ALEN] __aligned(2) = {
>  		0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00
>  	};
>  
> +	if (s1g)

no need to introduce the 's1g' variable, and it sounds weird anyway
because s1g uses other frames too, not just beacons

> @@ -5175,11 +5183,13 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx,
>  	}
>  
>  	/* Store a copy of the pre-translated link addresses for SW crypto */
> -	if (unlikely(is_unicast_ether_addr(hdr->addr1) &&
> +	if (unlikely(!ieee80211_is_s1g_beacon(hdr->frame_control) &&
> +		     is_unicast_ether_addr(hdr->addr1) &&
>  		     !ieee80211_is_data(hdr->frame_control)))
>  		memcpy(rx->link_addrs, &hdr->addrs, 3 * ETH_ALEN);
>  
>  	if (unlikely(rx->sta && rx->sta->sta.mlo) &&
> +	    !ieee80211_is_s1g_beacon(hdr->frame_control) &&
>  	    is_unicast_ether_addr(hdr->addr1) &&
>  	    !ieee80211_is_probe_resp(hdr->frame_control) &&
>  	    !ieee80211_is_beacon(hdr->frame_control)) {

This seems very ... specific, and doing the same thing twice also seems
odd. While not great, I'd probably advocate for a goto or just doing the
invoke() separately for s1g beacons.

> @@ -5260,23 +5270,30 @@ static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx,
>  {
>  	struct link_sta_info *link_sta;
>  	struct ieee80211_hdr *hdr = (void *)skb->data;
> +	u8 *sta_addr = hdr->addr2;
>  	struct sta_info *sta;
>  	int link_id = -1;
>  
> +	if (ieee80211_is_s1g_beacon(hdr->frame_control)) {
> +		sta_addr = ieee80211_get_bssid(hdr, skb->len, rx->sdata->vif.type);
> +		if (!sta_addr)
> +			return false;
> +	}

That one seems even weirder - especially in the face of your *other*
changes that attempt to never access hdr-> without making sure it's
actually the right format ... you still create a pointer to addr2 here.
It's valid since you never use it, but it's also weird because it pretty
much looks like hdr->addr2 _is_ OK at the whole function level.

> +
>  	/*
>  	 * Look up link station first, in case there's a
>  	 * chance that they might have a link address that
>  	 * is identical to the MLD address, that way we'll
>  	 * have the link information if needed.
>  	 */
> -	link_sta = link_sta_info_get_bss(rx->sdata, hdr->addr2);
> +	link_sta = link_sta_info_get_bss(rx->sdata, sta_addr);

Obviously, if things work today, we didn't really need the link_sta for
these frames, and that makes some sense since there's no MLO and it's
just ieee80211_rx_mgmt_beacon() basically. Probably better to just skip
this entirely and handle s1g beacons separately.

>  	if (link_sta) {
>  		sta = link_sta->sta;
>  		link_id = link_sta->link_id;
>  	} else {
>  		struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
>  
> -		sta = sta_info_get_bss(rx->sdata, hdr->addr2);
> +		sta = sta_info_get_bss(rx->sdata, sta_addr);
>  		if (status->link_valid) {
>  			link_id = status->link_id;
>  		} else if (ieee80211_vif_is_mld(&rx->sdata->vif) &&
> @@ -5347,6 +5364,12 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
>  		return;
>  	}
>  
> +	if (ieee80211_is_s1g_beacon(fc) &&
> +	    !pskb_may_pull(skb, ieee80211_s1g_beacon_min_len(fc))) {
> +		dev_kfree_skb(skb);
> +		return;
> +	}

I'm fairly certain this still leaves things (e.g.
ieee80211_rx_mgmt_beacon()) wrong if the driver ever reports an s1g
beacon as a frag skb.

I think much better to just treat this frame like mgmt frames and
linearize it earlier in the function along with mgmt frames etc. Still
need to check the length, but we could even do that there as well,
rather than this late.

johannes

  reply	other threads:[~2026-06-11 12:03 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-10 16:27 Zhao Li
2026-06-11 12:03 ` Johannes Berg [this message]
2026-06-11 16:19 ` [PATCH v2 0/2] wifi: handle S1G and extension-frame RX layout Zhao Li
2026-06-11 16:19   ` [PATCH v2 1/2] wifi: mac80211: validate extension-frame layout before RX Zhao Li
2026-06-11 16:19   ` [PATCH v2 2/2] wifi: cfg80211: derive S1G beacon TSF from S1G fields Zhao Li
2026-06-12  2:28     ` Lachlan Hodges
2026-06-12  0:54   ` [PATCH v2 0/2] wifi: handle S1G and extension-frame RX layout Lachlan Hodges

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2dbb5e703e5d7fa787c9f0debcedb3dc73c1643d.camel@sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=enderaoelyther@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=thomas@adapt-ip.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®