Netdev List
 help / color / mirror / Atom feed
From: Daniel Machon <daniel.machon@microchip.com>
To: <netdev-bot+sashiko@kernel.org>
Cc: <andrew+netdev@lunn.ch>, <davem@davemloft.net>,
	<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
	<horatiu.vultur@microchip.com>, <steen.hegelund@microchip.com>,
	<UNGLinuxDriver@microchip.com>, <ast@kernel.org>,
	<daniel@iogearbox.net>, <hawk@kernel.org>,
	<john.fastabend@gmail.com>, <sdf@fomichev.me>,
	<herve.codina@bootlin.com>, <arnd@arndb.de>,
	<gregkh@linuxfoundation.org>, <mohsin.bashr@gmail.com>,
	<horms@kernel.org>, <richardcochran@gmail.com>,
	<netdev@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<bpf@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH net-next v8 13/15] net: lan966x: add PCIe FDMA XDP support
Date: Mon, 28 Sep 2026 13:02:18 +0200	[thread overview]
Message-ID: <20260928110218.ktlj26jtyakuywio@DEN-DL-M70577> (raw)
In-Reply-To: <179036955220.2160803.7046320782670912992@kernel.org>

> Thank you for your contribution! Sashiko AI review found 3 potential
> issue(s) to consider.
> 
> Critical: 1 · High: 0 · Medium: 2 · Low: 0
> 
> 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).
> 
> - [Critical] Use-after-free and double free on the PCIe RX path when an
>   XDP program shrinks a frame.
> - [Medium] On the PCIe path the driver accepts XDP but cannot handle
>   XDP_REDIRECT, and the bond driver cannot tell.
> - [Medium] In lan966x_fdma_pci_napi_poll(), a poll that consumes all
>   FDMA_PCI_DCB_MAX (256) RX descriptors never re-arms any of them.
> 
> --
> 
> net: lan966x: add PCIe FDMA XDP support
> 
> This commit adds basic XDP support (XDP_PASS, XDP_DROP, XDP_TX) to the
> lan966x PCIe FDMA path. The IFH and FCS are stripped before the program
> runs, and the pointer and length from after XDP are passed on to skb
> construction or to a new memcpy-based XDP_TX routine.
> lan966x_xdp_setup() now accepts programs on PCIe and skips the page_pool
> reload there.
> 
> > diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c
> > index 7185e65dda435..216e9cbcd1580 100644
> > --- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c
> > +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c
> 
> [ ... ]
> 
> > +static int lan966x_xdp_pci_run(struct lan966x_port *port, void *data,
> > +                            u32 data_len, void **xdp_data, u32 *xdp_len)
> > +{
> 
> [ ... ]
> 
> > +     act = bpf_prog_run_xdp(xdp_prog, &xdp);
> > +
> > +     *xdp_data = xdp.data;
> > +     *xdp_len = xdp.data_end - xdp.data;
> > +
> > +     switch (act) {
> > +     case XDP_PASS:
> > +             return FDMA_PASS;
> > +     case XDP_TX:
> > +             return lan966x_fdma_pci_xmit_xdpf(port, *xdp_data, *xdp_len) ?
> > +                    FDMA_DROP : FDMA_TX;
> > +     default:
> > +             bpf_warn_invalid_xdp_action(port->dev, xdp_prog, act);
> > +             fallthrough;
> 
> [Severity: Medium]
> What happens here when the PCIe port is a bond slave?
> 
> The PCIe ports use the same lan966x_port_netdev_ops as the platform
> ports, so both .ndo_bpf and .ndo_xdp_xmit are set. bond_xdp_set() looks
> only at those pointers and never reads xdp_features:
> 
> drivers/net/bonding/bond_main.c:bond_xdp_set() {
>     ...
>                 if (!slave_dev->netdev_ops->ndo_bpf ||
>                     !slave_dev->netdev_ops->ndo_xdp_xmit) {
>     ...
> }
> 
> This patch removes the -EOPNOTSUPP return for PCIe in
> lan966x_xdp_setup(), so a bond with a lan966x PCIe slave can now install
> its program on that slave. For bond slaves, bpf_prog_run_xdp() can then
> turn XDP_TX into XDP_REDIRECT:
> 
> net/core/filter.c:xdp_master_redirect() {
>     ...
>         if (slave && slave != xdp->rxq->dev) {
>                 ri->tgt_index = slave->ifindex;
>                 ri->map_id = INT_MAX;
>                 ri->map_type = BPF_MAP_TYPE_UNSPEC;
>                 return XDP_REDIRECT;
>     ...
> }
> 
> It can also return XDP_ABORTED when the master is down.
> 
> This switch has no XDP_REDIRECT case. Would those frames go to the
> default branch, log a "Driver unsupported" warning and be dropped?
> Nothing calls xdp_do_redirect(), so the redirect info set by
> xdp_master_redirect() would never be used.

Re-raise of dismissed issue in v7.

> 
> [ ... ]
> 
> >  static struct sk_buff *lan966x_fdma_pci_rx_get_frame(struct lan966x_rx *rx,
> > -                                                  u64 src_port)
> > +                                                  u64 src_port, void *data,
> > +                                                  u32 data_len)
> >  {
> 
> [ ... ]
> 
> > -     memcpy(skb->data,
> > -            fdma_dataptr_virt_addr_contiguous(fdma,
> > -                                              fdma->dcb_index,
> > -                                              fdma->db_index),
> > -                                              data_len);
> > +     memcpy(skb->data, data, data_len);
> >
> >       skb_put(skb, data_len);
> >
> >       skb->dev = lan966x->ports[src_port]->dev;
> > -     skb_pull(skb, IFH_LEN_BYTES);
> > -
> > -     skb_trim(skb, skb->len - ETH_FCS_LEN);
> >
> >       skb->protocol = eth_type_trans(skb, skb->dev);
> 
> [Severity: Critical]
> Can this lead to a use-after-free when an XDP program shrinks the frame?
> 
> data_len is now the length from after XDP, returned by
> lan966x_xdp_pci_run(). bpf_xdp_adjust_tail() and bpf_xdp_adjust_head()
> let it shrink to ETH_HLEN. Take a 14-byte frame with h_proto 0x8100
> that returns XDP_PASS. eth_type_trans() then leaves skb->len == 0 and
> skb->protocol == ETH_P_8021Q.
> 
> Now suppose src_port is in bridge_mask and IGMP/MLD redirect is enabled
> in ANA_CPU_FWD_CFG. lan966x_port_mc_set() enables it when multicast
> snooping is on, and snooping is on by default. In that case the code
> after this point reaches:
> 
> drivers/net/ethernet/microchip/lan966x/lan966x_main.c:lan966x_hw_offload() {
>     ...
>         if (eth_type_vlan(skb->protocol)) {
>                 skb = skb_vlan_untag(skb);
>                 if (unlikely(!skb))
>                         return false;
>         }
>     ...
> }
> 
> pskb_may_pull(skb, VLAN_HLEN + 2) fails in skb_vlan_untag(), so it
> frees the skb with kfree_skb() and returns NULL. lan966x_hw_offload()
> only returns a bool, so the caller still holds the freed pointer:
> 
>                 if (!lan966x_hw_offload(lan966x, src_port, skb))
>                         skb->offload_fwd_mark = 0;
>         }
> 
>         skb->dev->stats.rx_bytes += skb->len;
> 
> The freed skb is then returned to lan966x_fdma_pci_napi_poll(), which
> passes it to napi_gro_receive(). Would that be a use-after-free followed
> by a double free?
> 
> The problem in lan966x_hw_offload() is older. Before this patch it could
> not be reached, because skbs were built from the hardware length and the
> MAC drops runts. The frame contents can also come from the network, for
> example when a decap program uses adjust_head on a minimum-size outer
> frame.

A VLAN-tag frame arrives on a bridged port, with IGMP/MLD snooping enabled. That
same port has an XDP program that shrinks the frame to ETH_HLEN and returns
XDP_PASS. AFAICT, yes, that will result in UAF.

Agree that the problem is lan966x_hw_offload, which can potentially free the
skb, without letting the caller know. This function is pre-existing and used in
the platform path, but the UAF can never happen there, because the frame length
is guarded, and the post-program length is not used at all.

Since there is no live bug in the platform path today, this should, IMO, be a
preparatory commit in this series, that refactors the lan966x_hw_offload()
function to let the caller know the skb was freed.

> 
> [ ... ]
> 
> > @@ -312,8 +430,17 @@ static int lan966x_fdma_pci_napi_poll(struct napi_struct *napi, int weight)
> >                        */
> >                       fdma_dcb_advance(fdma);
> >                       continue;
> > +             case FDMA_TX:
> > +                     fdma_dcb_advance(fdma);
> > +                     continue;
> > +             case FDMA_DROP:
> > +                     fdma_dcb_advance(fdma);
> > +                     continue;
> >               }
> 
> [Severity: Medium]
> What happens if one poll consumes all 256 (FDMA_PCI_DCB_MAX) RX
> descriptors?
> 
> Every result path calls fdma_dcb_advance(), which wraps at n_dcbs. After
> 256 frames, dcb_index is back at the value saved in dcb_reload. The
> re-arm loop at the end of lan966x_fdma_pci_napi_poll() then runs zero
> times:
> 
>         while (dcb_reload != fdma->dcb_index) {
>                 old_dcb = dcb_reload;
>                 dcb_reload++;
>                 dcb_reload &= fdma->n_dcbs - 1;
> 
> So none of the consumed DCBs are re-armed, and they all keep
> FDMA_DCB_STATUS_DONE. With a budget above 256, fdma_has_frames() stays
> true and the same frames are processed again in the same call. With a
> budget of exactly 256, the next poll processes them again.
> 
> Would this deliver stale frames twice, run XDP on them again, and resend
> the XDP_TX frames?
> 
> Only the budget bounds the loop. __napi_busy_loop() passes the socket's
> SO_BUSY_POLL_BUDGET straight to napi_poll(), and that value can be up to
> U16_MAX with CAP_NET_ADMIN. The ring can fill completely, because the
> hardware fills the last DCB before it stops on the invalid nextptr.
> 
> This loop was added by the earlier "net: lan966x: add PCIe FDMA support"
> commit in this series. This patch extends it with the XDP_TX and
> XDP_DROP results, and it does not seem to be fixed later in the series.
> The platform lan966x_fdma_napi_poll() has the same pattern with 512
> DCBs.

Re-raise of dismissed issue in v7.

> 
> --
> Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260924-lan966x-pci-fdma-v8-0-201c7b707d8b%40microchip.com

pw-bot: cr

  reply	other threads:[~2026-09-28 11:02 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-24 19:56 [PATCH net-next v8 00/15] net: lan966x: add support for PCIe FDMA Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 01/15] MAINTAINERS: add FDMA library to Sparx5 SoC entry Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 02/15] net: microchip: fdma: rename contiguous dataptr helpers Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 03/15] net: microchip: fdma: add PCIe ATU support Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-24 19:56 ` [PATCH net-next v8 04/15] net: microchip: fdma: use little-endian types for descriptor fields Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 05/15] net: lan966x: add FDMA LLP register write helper Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 06/15] net: lan966x: export FDMA helpers for reuse Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 07/15] net: lan966x: use a dedicated device for DMA operations Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 08/15] net: lan966x: add FDMA ops dispatch for PCIe support Daniel Machon
2026-09-24 19:56 ` [PATCH net-next v8 09/15] net: lan966x: clear FDMA interrupt stickies after switch reset Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-24 19:56 ` [PATCH net-next v8 10/15] net: lan966x: add shutdown callback to stop the FDMA on reboot Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-24 19:56 ` [PATCH net-next v8 11/15] net: lan966x: add PCIe FDMA support Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-24 19:57 ` [PATCH net-next v8 12/15] net: lan966x: add PCIe FDMA MTU change support Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-24 19:57 ` [PATCH net-next v8 13/15] net: lan966x: add PCIe FDMA XDP support Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-28 11:02     ` Daniel Machon [this message]
2026-09-24 19:57 ` [PATCH net-next v8 14/15] misc: lan966x-pci: dts: extend cpu reg to cover PCIE DBI space Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko
2026-09-24 19:57 ` [PATCH net-next v8 15/15] misc: lan966x-pci: dts: add fdma interrupt to overlay Daniel Machon
2026-09-25 20:52   ` netdev-bot+sashiko

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=20260928110218.ktlj26jtyakuywio@DEN-DL-M70577 \
    --to=daniel.machon@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=arnd@arndb.de \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hawk@kernel.org \
    --cc=herve.codina@bootlin.com \
    --cc=horatiu.vultur@microchip.com \
    --cc=horms@kernel.org \
    --cc=john.fastabend@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mohsin.bashr@gmail.com \
    --cc=netdev-bot+sashiko@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=richardcochran@gmail.com \
    --cc=sdf@fomichev.me \
    --cc=steen.hegelund@microchip.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