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 --]
next prev parent reply other threads:[~2026-10-20 13:29 UTC|newest]
Thread overview: 25+ 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:07 ` sashiko-bot
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.