Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
To: netdev-bot+sashiko@kernel.org
Cc: maxime.chevallier@bootlin.com, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
	pabeni@redhat.com, mcoquelin.stm32@gmail.com,
	alexandre.torgue@foss.st.com, ast@kernel.org,
	daniel@iogearbox.net, hawk@kernel.org, john.fastabend@gmail.com,
	sdf@fomichev.me, Jose.Abreu@synopsys.com,
	boon.leong.ong@intel.com, netdev@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, bpf@vger.kernel.org
Subject: Re: [PATCH net-next v8 4/5] net: stmmac: fix VLAN tag stripping on non-linear RX frames
Date: Tue, 20 Oct 2026 15:29:40 +0200	[thread overview]
Message-ID: <atdsxFPHU00Oc0Zk@lore-desk> (raw)
In-Reply-To: <179243151841.3135.10232947668205235199@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 9467 bytes --]

> Thank you for your contribution! Sashiko AI review found 3 potential
> issue(s) to consider.
> 
> Critical: 0 · High: 0 · Medium: 2 (1) · Low: 1
> 
> If you believe none of the issues are legitimate, please reply to each
> issue of Medium severity or higher and explain why the AI is wrong.
> If any of them are legitimate and you plan to respin, please let patchwork
> know by including "pw-bot: cr" as a separate line at the end of your reply
> (one such reply per series is enough).
> 
> - [Medium] The commit message and Fixes: tag describe a crash that cannot
>   happen in any tree this patch would be backported to.
> - [Medium] The commit message says that moving meta_len bytes together
>   with the MAC addresses in stmmac_rx_vlan() keeps data_meta pointing at…
> - [Low] stmmac_rx_vlan() now calls pskb_may_pull(skb, VLAN_ETH_HLEN)
>   before checking h_vlan_proto or dev->features.
> 
> Pre-existing issues:
> - [Medium] This problem wasn't introduced by this patch, but
>   priv->xstats.rx_dropped is a plain 'unsigned long' (common.h:241)…
> 
> --
> 
> net: stmmac: fix VLAN tag stripping on non-linear RX frames
> 
> This patch makes stmmac_rx_vlan() call pskb_may_pull(skb, VLAN_ETH_HLEN)
> before it reads the VLAN header. When the tag is popped, any XDP metadata
> is now moved along with the MAC addresses. If the pull fails, both RX
> callers drop the frame.
> 
> > stmmac_rx_vlan() reads the VLAN header straight from skb->data and
> > removes it with skb_pull(), assuming the header is always in the linear
> > part of the skb. That is not true once non-linear skbs can reach it: a
> > program loaded with BPF_F_XDP_HAS_FRAGS can pass up a fragmented frame
> > whose linear head has been shortened to as little as ETH_HLEN by
> > bpf_xdp_adjust_head(), and the unguarded skb_pull() then drives skb->len
> > below skb->data_len, tripping BUG() in __skb_pull().
> 
> [Severity: Medium]
> Can this scenario happen in a tree that matches the Fixes: tag?
> 
> On the AF_XDP zero-copy path from bba2556efad6, stmmac_construct_skb_zc()
> always builds a linear skb:
> 
> 	skb = napi_alloc_skb(&ch->rxtx_napi,
> 			     xdp->data_end - xdp->data_hard_start);
> 	...
> 	memcpy(__skb_put(skb, datasize), xdp->data, datasize);
> 
> On the regular stmmac_rx() path with XDP enabled, multi-descriptor frames
> and buf2 frames are both dropped:
> 
> 		/* We do not support SG in XDP mode */
> 		if (unlikely(!error && (status & rx_not_ls) &&
> 			     stmmac_xdp_is_enabled(priv))) {
> 		...
> 		if (unlikely(stmmac_xdp_is_enabled(priv) && buf2_len)) {
> 			rx_dropped++;
> 			goto next;
> 		}
> 
> The XDP_PASS skb there is built with napi_build_skb() plus
> skb_put(buf1_len) and has no frags. XDP_PASS skbs with frags seem to
> appear only with the later "net: stmmac: rework stmmac_rx to support XDP
> rx multi-buff" patch in this series.
> 
> Even with a 14 byte linear head, skb_pull(skb, VLAN_HLEN) here would leave
> 10 bytes of headlen and would not BUG. Wouldn't the BUG() come from
> eth_type_trans()->eth_skb_pull_mac()->skb_pull_inline(skb, ETH_HLEN)
> instead?
> 
> On current trees, the patch fixes a different case. An XDP program can
> use bpf_xdp_adjust_tail() to shrink a linear frame to 14..17 bytes while
> bytes 12-13 still hold a VLAN ethertype. The old code then reads
> h_vlan_TCI past skb->len and pops the tag. That leaves skb->len below
> ETH_HLEN, and eth_type_trans() passes a malformed skb up the stack.
> 
> Could the commit message describe that case, and could the Fixes: tag be
> rechecked? As written, stable maintainers may conclude that 5.13+ kernels
> hit a BUG() they do not have.

I will fix it in the next iteration.

> 
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > index e929cc0f23125..04dc6dcaa435d 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > @@ -5095,22 +5095,30 @@ static netdev_features_t stmmac_features_check(struct sk_buff *skb,
> >  	return vlan_features_check(skb, features);
> >  }
> >  
> > -static void stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
> > +static int stmmac_rx_vlan(struct net_device *dev, struct sk_buff *skb)
> >  {
> > -	struct vlan_ethhdr *veth = skb_vlan_eth_hdr(skb);
> > -	__be16 vlan_proto = veth->h_vlan_proto;
> > -	u16 vlanid;
> > +	struct vlan_ethhdr *veth;
> >  
> > -	if ((vlan_proto == htons(ETH_P_8021Q) &&
> > +	if (!pskb_may_pull(skb, VLAN_ETH_HLEN))
> > +		return -EINVAL;
> 
> [Severity: Low]
> Does this drop every 14..17 byte frame, including untagged ones?

I will fix it in the next iteration.

> 
> The pull happens before h_vlan_proto and dev->features are checked. Any
> skb with skb->len < VLAN_ETH_HLEN now fails here, and both stmmac_rx()
> and stmmac_dispatch_skb_zc() free it and count it in rx_dropped.
> 
> This also covers interfaces set with "ethtool -K rxvlan off". There,
> stmmac_set_features() clears hw_vlan_en, so stmmac_rx_vlan() runs for
> every frame. It also covers non-xmac cores, where hw_vlan_en is never
> set.
> 
> Such frames can come from an XDP program that shrinks a frame with
> bpf_xdp_adjust_tail(), which allows lengths down to ETH_HLEN, and then
> returns XDP_PASS. Before this patch they went through eth_type_trans()
> unchanged.
> 
> Would it work to check the ethertype and features first? ETH_HLEN is
> enough to read h_vlan_proto, and VLAN_ETH_HLEN would only be needed
> when the tag is about to be popped.
> 
> > +
> > +	veth = skb_vlan_eth_hdr(skb);
> > +	if ((veth->h_vlan_proto == htons(ETH_P_8021Q) &&
> >  	     dev->features & NETIF_F_HW_VLAN_CTAG_RX) ||
> > -	    (vlan_proto == htons(ETH_P_8021AD) &&
> > +	    (veth->h_vlan_proto == htons(ETH_P_8021AD) &&
> >  	     dev->features & NETIF_F_HW_VLAN_STAG_RX)) {
> > +		__be16 vlan_proto = veth->h_vlan_proto;
> > +		u16 vlanid = ntohs(veth->h_vlan_TCI);
> > +		u8 meta_len = skb_metadata_len(skb);
> > +
> >  		/* pop the vlan tag */
> > -		vlanid = ntohs(veth->h_vlan_TCI);
> > -		memmove(skb->data + VLAN_HLEN, veth, ETH_ALEN * 2);
> > +		memmove(skb->data - meta_len + VLAN_HLEN,
> > +			skb->data - meta_len, meta_len + ETH_ALEN * 2);
> 
> [Severity: Medium]
> On the AF_XDP zero-copy path, do the meta_len bytes before skb->data
> actually hold the XDP metadata?

I guess this issue is not introduced by this series. I will fix it with a
dedicated patch.

> 
> stmmac_construct_skb_zc() records the metadata length but never copies
> the metadata bytes:
> 
> 	skb_reserve(skb, xdp->data - xdp->data_hard_start);
> 	memcpy(__skb_put(skb, datasize), xdp->data, datasize);
> 	if (metasize)
> 		skb_metadata_set(skb, metasize);
> 
> The skb comes from napi_alloc_skb(), which does not zero the headroom,
> so the bytes in front of skb->data are stale. This memmove() moves those
> stale bytes in front of the relocated MAC header.
> 
> After eth_type_trans(), bpf_compute_data_pointers() sets data_meta to
> skb->data - skb_metadata_len(skb). TC BPF programs would then read
> uninitialized headroom instead of what the XDP program wrote.
> 
> On the regular stmmac_rx() path, skb_metadata_set() is never called at
> this commit. meta_len is therefore always 0 there, and this part of the
> change does nothing until the later rework patch adds the call in
> stmmac_build_skb(). stmmac_construct_skb_zc() is still unchanged at the
> end of the series.
> 
> Peer drivers such as igc_construct_skb_zc() copy starting at
> xdp->data_meta and then call __skb_pull(skb, metasize). Should
> stmmac_construct_skb_zc() do the same, or should the metadata claim come
> out of the commit message?
> 
> >  		skb_pull(skb, VLAN_HLEN);
> >  		__vlan_hwaccel_put_tag(skb, vlan_proto, vlanid);
> >  	}
> 
> [ ... ]
> 
> > @@ -5530,12 +5538,15 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
> >  	}
> >  
> >  	stmmac_get_rx_hwtstamp(priv, p, np, skb);
> > -	if (priv->hw->hw_vlan_en)
> > +	if (priv->hw->hw_vlan_en) {
> >  		/* MAC level stripping. */
> >  		stmmac_rx_hw_vlan(priv, priv->hw, p, skb);
> > -	else
> > -		/* Driver level stripping. */
> > -		stmmac_rx_vlan(priv->dev, skb);
> > +	} else if (stmmac_rx_vlan(priv->dev, skb)) {
> > +		dev_kfree_skb_any(skb);
> > +		priv->xstats.rx_dropped++;
> 
> [Severity: Medium]
> This isn't a bug introduced by this patch, but priv->xstats.rx_dropped is
> a plain unsigned long shared by all RX queues. Per-queue NAPI contexts,
> which can run at the same time on different CPUs, update it with
> unsynchronized read-modify-write:

Since this issue has not been introduced by this patch I guess we can fix it
with a dedicated patch.

Regards,
Lorenzo

> 
> stmmac_dispatch_skb_zc():
> 	priv->xstats.rx_dropped++;
> 
> stmmac_rx_zc() and stmmac_rx():
> 	priv->xstats.rx_dropped += rx_dropped;
> 
> stmmac_get_stats64() also reads it without READ_ONCE().
> 
> Can concurrent updates from two queues lose increments here? The new
> error path adds one more writer that follows the existing pattern.
> 
> > +		return;
> > +	}
> 
> [ ... ]
> 
> -- 
> Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261018-stmmac-rx-mb-v8-0-5f58c0b25849%40oss.qualcomm.com

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

  reply	other threads:[~2026-10-20 13:29 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-18 17:06 [PATCH net-next v8 0/5] net: stmmac: introduce XDP rx multi-buff support Lorenzo Bianconi
2026-10-18 17:06 ` [PATCH net-next v8 1/5] net: stmmac: take ownership of saved RX state at poll entry Lorenzo Bianconi
2026-10-19 17:38   ` netdev-bot+sashiko
2026-10-20 13:16     ` Lorenzo Bianconi
2026-10-18 17:07 ` [PATCH net-next v8 2/5] net: stmmac: drop split frames on AF_XDP zero-copy RX Lorenzo Bianconi
2026-10-19 11:16   ` Nicolai Buchwitz
2026-10-19 12:17     ` Lorenzo Bianconi
2026-10-19 12:30       ` Nicolai Buchwitz
2026-10-19 17:38   ` netdev-bot+sashiko
2026-10-20 13:20     ` Lorenzo Bianconi
2026-10-18 17:07 ` [PATCH net-next v8 3/5] net: stmmac: drop multi-buffer frames in XDP mode Lorenzo Bianconi
2026-10-19 11:08   ` Nicolai Buchwitz
2026-10-19 17:38   ` netdev-bot+sashiko
2026-10-20 13:25     ` Lorenzo Bianconi
2026-10-18 17:07 ` [PATCH net-next v8 4/5] net: stmmac: fix VLAN tag stripping on non-linear RX frames Lorenzo Bianconi
2026-10-19 11:08   ` Nicolai Buchwitz
2026-10-19 17:38   ` netdev-bot+sashiko
2026-10-20 13:29     ` Lorenzo Bianconi [this message]
2026-10-18 17:07 ` [PATCH net-next v8 5/5] net: stmmac: rework stmmac_rx to support XDP rx multi-buff Lorenzo Bianconi
2026-10-19 11:10   ` Nicolai Buchwitz
2026-10-19 17:38   ` netdev-bot+sashiko
2026-10-20 13:32     ` Lorenzo Bianconi
2026-10-18 17:08 ` [PATCH net-next v8 0/5] net: stmmac: introduce XDP rx multi-buff support netdev-bot+sinfo
2026-10-18 17:19   ` Lorenzo Bianconi

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=atdsxFPHU00Oc0Zk@lore-desk \
    --to=lorenzo.bianconi@oss.qualcomm.com \
    --cc=Jose.Abreu@synopsys.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=ast@kernel.org \
    --cc=boon.leong.ong@intel.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=hawk@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=maxime.chevallier@bootlin.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=netdev-bot+sashiko@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@fomichev.me \
    /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