Linux kernel and device drivers for NXP i.MX platforms
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: wei.fang@oss.nxp.com
Cc: Frank.Li@kernel.org, imx@lists.linux.dev
Subject: Re: [PATCH net-next 7/7] net: dsa: netc: add PTP one-step timestamping support
Date: Wed, 29 Jul 2026 10:43:16 +0000	[thread overview]
Message-ID: <20260729104316.EABB81F00AC4@smtp.kernel.org> (raw)
In-Reply-To: <20260728104548.3301214-8-wei.fang@oss.nxp.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] The in-flight one-step Sync SKB outlives the DSA port structures on driver unbind, causing a Use-After-Free in the SKB destructor.
- [High] The unbounded skb_onestep_queue can cause an Out-Of-Memory (OOM) crash if an attacker floods the port with forwarded PTP Sync packets.
- [High] Calling ptp_parse_header() without ensuring the packet headers are in the linear data area causes an out-of-bounds read on fragmented packets.
- [Medium] Modifying the PTP originTimestamp in software without updating the UDP checksum breaks the checksum for non-offloaded packets.
--

--- Patch [7]: [PATCH net-next 7/7] net: dsa: netc: add PTP one-step timestamping support ---
commit df83cf11f57c79cb36a98872a09e3e01dbf7936a
Author: Wei Fang <wei.fang@nxp.com>

net: dsa: netc: add PTP one-step timestamping support

This commit adds one-step TX timestamping support for PTP Sync frames on the
NETC switch. It implements serialization of one-step Sync transmission per
port and intercepts packets to program the PTP originTimestamp before handing
the frame to the hardware.

> diff --git a/drivers/net/dsa/netc/netc_main.c b/drivers/net/dsa/netc/netc_main.c
> --- a/drivers/net/dsa/netc/netc_main.c
> +++ b/drivers/net/dsa/netc/netc_main.c
[ ... ]
> @@ -1011,6 +1014,8 @@ static void netc_free_ports_resources(struct netc_switch *priv)
>  		 * (sock_efree) while holding a spinlock.
>  		 */
>  		__skb_queue_purge(&np->skb_txtstamp_queue);
> +		cancel_work_sync(&np->onestep_work);
> +		__skb_queue_purge(&np->skb_onestep_queue);

[Severity: High]
Does this teardown path need to wait for or cancel in-flight packets that
were already handed off to the conduit device? Local queues are purged, but
an SKB currently in-flight might retain a pointer to the port structure in
its destructor.

>  	}
>  }
> diff --git a/drivers/net/dsa/netc/netc_ptp.c b/drivers/net/dsa/netc/netc_ptp.c
> --- a/drivers/net/dsa/netc/netc_ptp.c
> +++ b/drivers/net/dsa/netc/netc_ptp.c
[ ... ]
> +static void netc_port_prepare_onestep_sync(struct netc_port *np,
> +					   struct sk_buff *skb,
> +					   u32 ptp_class, bool *twostep)
> +{
> +	struct netc_switch *priv = np->switch_priv;
> +	u16 correction_offset, timestamp_offset;
> +	struct ptp_header *ptp_hdr;
> +	u8 msg_type, twostep_flag;
> +	bool is_udp = false;
> +	u32 pkt_type;
> +	u8 *pkt_hdr;
> +
> +	ptp_hdr = ptp_parse_header(skb, ptp_class);
> +	if (!ptp_hdr) {

[Severity: High]
Does calling ptp_parse_header() here risk an out-of-bounds read if the
packet is fragmented? The function directly accesses the IP header, but the
code hasn't verified that the headers are in the linear data area using
pskb_may_pull() yet. The bounds check later in this function happens after
the read has already occurred.

> +		dev_dbg_ratelimited(priv->dev,
> +				    "Port %d failed to parse Sync header\n",
> +				    np->dp->index);
> +		return;
> +	}
[ ... ]
> +static void netc_port_program_onestep(struct netc_port *np,
> +				      struct sk_buff *skb,
> +				      u64 tstamp)
> +{
> +	u16 correction_offset = NETC_SKB_CB(skb)->correction_offset;
> +	u16 timestamp_offset = NETC_SKB_CB(skb)->timestamp_offset;
> +	bool is_udp = NETC_SKB_CB(skb)->is_udp;
> +	u8 *pkt_hdr = skb_mac_header(skb);
> +	u64 sec;
> +	u32 ns;
> +
> +	NETC_SKB_CB(skb)->tstamp = tstamp;
> +	NETC_SKB_CB(skb)->ptp_flag = NETC_PTP_FLAG_ONESTEP;
> +
> +	/* Update originTimestamp field of Sync packet
> +	 * - 48 bits seconds field
> +	 * - 32 bits nanoseconds field
> +	 */
> +	sec = div_u64_rem(tstamp, NSEC_PER_SEC, &ns);
> +	put_unaligned_be16((sec >> 32) & 0xffff, pkt_hdr + timestamp_offset);
> +	put_unaligned_be32(sec & 0xffffffff, pkt_hdr + timestamp_offset + 2);
> +	put_unaligned_be32(ns, pkt_hdr + timestamp_offset + 6);

[Severity: Medium]
Does modifying the originTimestamp payload here break the UDP checksum for
non-offloaded packets? The hardware PM_SINGLE_STEP_CH feature only updates
the checksum for the residence time delta it adds to the correction field.
Do we need to incrementally update the software checksum for this payload
modification?

> +
> +	netc_port_set_onestep_control(np, is_udp, correction_offset);
> +
> +	/* Orphan the skb to release the socket send buffer quota immediately.
> +	 * This is safe because sock_wfree() only updates sk_wmem_alloc and
> +	 * does not touch skb->data. After skb_orphan(), we install our own
> +	 * destructor so that when the conduit driver frees the skb after TX
> +	 * completion, we get notified to send the next queued Sync packet.
> +	 */
> +	skb_orphan(skb);
> +	skb_shinfo(skb)->destructor_arg = np;
> +	skb->destructor = netc_onestep_skb_destructor;

[Severity: High]
Can this in-flight SKB outlive the netc_port structure during driver unbind?
If the driver unbinds while this packet is still queued in the conduit
device, the devres-managed netc_port will be freed. When the conduit device
later transmits and frees the SKB, will netc_onestep_skb_destructor()
dereference a freed pointer?

> +}
[ ... ]
> +struct sk_buff *netc_onestep_sync_handler(struct dsa_switch *ds, int port,
> +					  struct sk_buff *skb)
> +{
> +	struct netc_port *np = NETC_PORT(ds, port);
> +	struct netc_switch *priv = ds->priv;
> +	u64 tstamp;
> +
> +	/* Serialize one-step Sync packets: only one can be in-flight at a
> +	 * time because the SINGLE_STEP register is shared and must match the
> +	 * packet currently being transmitted. Claim the in-flight slot under
> +	 * ptp_lock. If another one-step Sync is already in-flight, queue this
> +	 * skb and return NULL; ownership is transferred to the queue, so no
> +	 * extra reference is needed and netc_xmit() stops processing it.
> +	 */
> +	spin_lock_bh(&np->ptp_lock);
> +	if (test_bit(NETC_FLAG_ONESTEP_IN_PROGRESS, &np->flags)) {
> +		__skb_queue_tail(&np->skb_onestep_queue, skb);
> +		spin_unlock_bh(&np->ptp_lock);
> +
> +		return NULL;

[Severity: High]
Is there a risk of memory exhaustion if an external source floods the port
with forwarded PTP Sync packets? Since this queue has no length limit and
returning NULL consumes the SKB, dsa_user_xmit() will return NETDEV_TX_OK,
bypassing qdisc backpressure mechanisms.

> +	}
> +
> +	tstamp = netc_timer_get_current_time(priv->tmr_dev);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260728104548.3301214-1-wei.fang@oss.nxp.com?part=7

      reply	other threads:[~2026-07-29 10:43 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-28 10:45 [PATCH net-next 0/7] net: dsa: netc: add PTP support for NETC switch wei.fang
2026-07-28 10:45 ` [PATCH net-next 1/7] ptp: netc: use ioread64_lo_hi/iowrite64_lo_hi for 64-bit register access wei.fang
2026-07-29 10:43   ` sashiko-bot
2026-07-28 10:45 ` [PATCH net-next 2/7] ptp: netc: remove unnecessary pcie_flr() call in probe wei.fang
2026-07-29 10:43   ` sashiko-bot
2026-07-28 10:45 ` [PATCH net-next 3/7] ptp: netc: export netc_timer_get_current_time() for cross-driver use wei.fang
2026-07-29 10:43   ` sashiko-bot
2026-07-28 10:45 ` [PATCH net-next 4/7] net: dsa: netc: use entry ID instead of pointer to track host flood rule wei.fang
2026-07-28 10:45 ` [PATCH net-next 5/7] net: dsa: netc: enable ingress port filtering lookup by default wei.fang
2026-07-28 10:45 ` [PATCH net-next 6/7] net: dsa: netc: add PTP two-step timestamping support wei.fang
2026-07-29 10:43   ` sashiko-bot
2026-07-29 13:41   ` Vadim Fedorenko
2026-07-28 10:45 ` [PATCH net-next 7/7] net: dsa: netc: add PTP one-step " wei.fang
2026-07-29 10:43   ` sashiko-bot [this message]

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=20260729104316.EABB81F00AC4@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=imx@lists.linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=wei.fang@oss.nxp.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