From: sashiko-bot@kernel.org
To: "Daniel Machon" <daniel.machon@microchip.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH net-next v3 09/13] net: lan966x: add PCIe FDMA support
Date: Tue, 05 May 2026 18:22:58 +0000 [thread overview]
Message-ID: <20260505182258.CFFDFC2BCB4@smtp.kernel.org> (raw)
In-Reply-To: <20260504-lan966x-pci-fdma-v3-9-a56f5740d870@microchip.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] Unconditional freeing of SKB in `lan966x_fdma_pci_xmit` causes a Use-After-Free if PTP hardware timestamping is enabled.
- [Critical] Freed SKB used in `lan966x_fdma_pci_rx_get_frame()` after `lan966x_hw_offload()` internally drops it, leading to a Use-After-Free.
- [High] PCIe TX path transmits uninitialized host memory due to incorrect `BLOCKL` calculation, causing an information leak.
- [High] RX buffer limit (`DATAL`) allows hardware to DMA write past the allocated buffer space, and bounds checks allow out-of-bounds memcpy.
--
commit 85d5f2d6dafac0733149c1d102524b3671cf0bef
Author: Daniel Machon <daniel.machon@microchip.com>
net: lan966x: add PCIe FDMA support
Add PCIe FDMA support for lan966x. The PCIe FDMA path uses contiguous
DMA buffers mapped through the endpoint's ATU, with memcpy-based frame
transfer instead of per-page DMA mappings.
> diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c
> new file mode 100644
> index 0000000000000..2c54880460772
> --- /dev/null
> +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma_pci.c
> @@ -0,0 +1,383 @@
> +// SPDX-License-Identifier: GPL-2.0+
[ ... ]
> +static int lan966x_fdma_pci_rx_alloc(struct lan966x_rx *rx)
> +{
> + struct lan966x *lan966x = rx->lan966x;
> + struct fdma *fdma = &rx->fdma;
> + int err;
> +
> + err = fdma_alloc_coherent_and_map(lan966x->dev, fdma, &lan966x->atu);
> + if (err)
> + return err;
> +
> + fdma_dcbs_init(fdma,
> + FDMA_DCB_INFO_DATAL(fdma->db_size),
> + FDMA_DCB_STATUS_INTR);
The DMA pointer given to hardware via fdma_dataptr_dma_addr_contiguous() is
offset by XDP_PACKET_HEADROOM. If we provide a DATAL limit of fdma->db_size,
won't a maximum-sized frame cause the hardware to write XDP_PACKET_HEADROOM
bytes past the end of the allocated DB space?
[ ... ]
> +static int lan966x_fdma_pci_rx_check_frame(struct lan966x_rx *rx, u64 *src_port)
> +{
> + struct lan966x *lan966x = rx->lan966x;
> + struct fdma *fdma = &rx->fdma;
> + struct lan966x_port *port;
> + struct fdma_db *db;
> + void *virt_addr;
> + u32 blockl;
> +
> + /* virt_addr points to the IFH. */
> + virt_addr = fdma_dataptr_virt_addr_contiguous(fdma,
> + fdma->dcb_index,
> + fdma->db_index);
> +
> + lan966x_ifh_get_src_port(virt_addr, src_port);
> +
> + if (WARN_ON(*src_port >= lan966x->num_phys_ports))
> + return FDMA_ERROR;
> +
> + port = lan966x->ports[*src_port];
> + if (!port)
> + return FDMA_ERROR;
> +
> + db = fdma_db_next_get(fdma);
> +
> + /* BLOCKL is a 16-bit HW-populated field; reject obviously-bad
> + * values before they feed memcpy/XDP sizes.
> + */
> + blockl = FDMA_DCB_STATUS_BLOCKL(db->status);
> + if (blockl < IFH_LEN_BYTES + ETH_FCS_LEN || blockl > fdma->db_size)
If blockl is greater than fdma->db_size - XDP_PACKET_HEADROOM, won't the
subsequent memcpy() in lan966x_fdma_pci_rx_get_frame() read out-of-bounds
into the next DB's memory?
[ ... ]
> +static struct sk_buff *lan966x_fdma_pci_rx_get_frame(struct lan966x_rx *rx,
> + u64 src_port)
> +{
> + struct lan966x *lan966x = rx->lan966x;
> + struct fdma *fdma = &rx->fdma;
> + struct sk_buff *skb;
> + struct fdma_db *db;
> + u32 data_len;
> +
> + /* Get the received frame and create an SKB for it. */
> + db = fdma_db_next_get(fdma);
> + data_len = FDMA_DCB_STATUS_BLOCKL(db->status);
> +
> + skb = napi_alloc_skb(&lan966x->napi, data_len);
> + if (unlikely(!skb))
> + return NULL;
> +
> + memcpy(skb->data,
> + fdma_dataptr_virt_addr_contiguous(fdma,
> + fdma->dcb_index,
> + fdma->db_index),
> + 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);
> +
> + if (lan966x->bridge_mask & BIT(src_port)) {
> + skb->offload_fwd_mark = 1;
> +
> + skb_reset_network_header(skb);
> + if (!lan966x_hw_offload(lan966x, src_port, skb))
> + skb->offload_fwd_mark = 0;
If lan966x_hw_offload() internally frees the SKB (for instance, if
skb_vlan_untag() fails) and returns false, won't this pointer dereference
cause a use-after-free here, and again when updating skb->dev->stats?
> + }
> +
> + skb->dev->stats.rx_bytes += skb->len;
> + skb->dev->stats.rx_packets++;
> +
> + return skb;
> +}
> +
> +static int lan966x_fdma_pci_xmit(struct sk_buff *skb, __be32 *ifh,
> + struct net_device *dev)
> +{
> + struct lan966x_port *port = netdev_priv(dev);
> + struct lan966x *lan966x = port->lan966x;
> + struct lan966x_tx *tx = &lan966x->tx;
> + struct fdma *fdma = &tx->fdma;
> + int next_to_use;
> + void *virt_addr;
> +
> + next_to_use = lan966x_fdma_pci_get_next_dcb(fdma);
> +
> + if (next_to_use < 0) {
> + netif_stop_queue(dev);
> + return NETDEV_TX_BUSY;
> + }
> +
> + if (skb_put_padto(skb, ETH_ZLEN)) {
> + dev->stats.tx_dropped++;
> + return NETDEV_TX_OK;
> + }
> +
> + if (!lan966x_fdma_pci_tx_size_fits(fdma, skb->len)) {
> + dev_kfree_skb_any(skb);
> + dev->stats.tx_dropped++;
> + return NETDEV_TX_OK;
> + }
> +
> + skb_tx_timestamp(skb);
> +
> + /* virt_addr points to the IFH. */
> + virt_addr = fdma_dataptr_virt_addr_contiguous(fdma, next_to_use, 0);
> + memcpy(virt_addr, ifh, IFH_LEN_BYTES);
> + memcpy(virt_addr + IFH_LEN_BYTES, skb->data, skb->len);
> +
> + /* Order frame write before DCB status write below. */
> + dma_wmb();
> +
> + fdma_dcb_add(fdma,
> + next_to_use,
> + 0,
> + FDMA_DCB_STATUS_INTR |
> + FDMA_DCB_STATUS_SOF |
> + FDMA_DCB_STATUS_EOF |
> + FDMA_DCB_STATUS_BLOCKO(0) |
> + FDMA_DCB_STATUS_BLOCKL(IFH_LEN_BYTES + skb->len + ETH_FCS_LEN));
Since we only copy IFH_LEN_BYTES + skb->len bytes to the DMA buffer, but we
configure the hardware BLOCKL to include ETH_FCS_LEN (4 extra bytes), could
the PCIe endpoint transmit uninitialized memory from previous packets
because the contiguous DMA buffers are reused?
> +
> + /* Start the transmission. */
> + lan966x_fdma_tx_start(tx);
> +
> + dev->stats.tx_bytes += skb->len;
> + dev->stats.tx_packets++;
> +
> + /* Safe to free: the PCIe DTBO does not enable the PTP interrupt,
> + * so lan966x->ptp stays 0 and lan966x_port_xmit() never enqueues
> + * this skb on port->tx_skbs for a TX timestamp.
> + */
> + dev_consume_skb_any(skb);
If a device tree does provide the 'ptp' IRQ, PTP will be enabled and
lan966x_port_xmit() will enqueue the SKB for hardware timestamping before
reaching this code. In that case, won't this unconditional
dev_consume_skb_any() free the SKB while it is still queued, leading to a
use-after-free when the PTP IRQ handler later processes it?
> +
> + return NETDEV_TX_OK;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260504-lan966x-pci-fdma-v3-0-a56f5740d870@microchip.com?part=9
next prev parent reply other threads:[~2026-05-05 18:22 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-04 14:23 [PATCH net-next v3 00/13] net: lan966x: add support for PCIe FDMA Daniel Machon
2026-05-04 14:23 ` [PATCH net-next v3 01/13] MAINTAINERS: add FDMA library to Sparx5 SoC entry Daniel Machon
2026-05-04 14:23 ` [PATCH net-next v3 02/13] net: microchip: fdma: rename contiguous dataptr helpers Daniel Machon
2026-05-04 14:23 ` [PATCH net-next v3 03/13] net: microchip: fdma: add PCIe ATU support Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 04/13] net: lan966x: add FDMA LLP register write helper Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 05/13] net: lan966x: export FDMA helpers for reuse Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 06/13] net: lan966x: add FDMA ops dispatch for PCIe support Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 07/13] net: lan966x: clear FDMA interrupt stickies after switch reset Daniel Machon
2026-05-04 14:23 ` [PATCH net-next v3 08/13] net: lan966x: add shutdown callback to stop FDMA on reboot Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 09/13] net: lan966x: add PCIe FDMA support Daniel Machon
2026-05-05 18:22 ` sashiko-bot [this message]
2026-05-07 8:54 ` Paolo Abeni
2026-05-07 9:21 ` Daniel Machon
2026-05-04 14:23 ` [PATCH net-next v3 10/13] net: lan966x: add PCIe FDMA MTU change support Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 11/13] net: lan966x: add PCIe FDMA XDP support Daniel Machon
2026-05-05 18:22 ` sashiko-bot
2026-05-04 14:23 ` [PATCH net-next v3 12/13] misc: lan966x-pci: dts: extend cpu reg to cover PCIE DBI space Daniel Machon
2026-05-04 14:23 ` [PATCH net-next v3 13/13] misc: lan966x-pci: dts: add fdma interrupt to overlay Daniel Machon
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=20260505182258.CFFDFC2BCB4@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel.machon@microchip.com \
--cc=sashiko@lists.linux.dev \
/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.