From: sashiko-bot@kernel.org
To: "Selvamani Rajagopal via B4 Relay"
<devnull+Selvamani.Rajagopal.onsemi.com@kernel.org>
Cc: devicetree@vger.kernel.org, conor+dt@kernel.org, robh@kernel.org
Subject: Re: [PATCH net-next v6 06/15] net: ethernet: oa_tc6: Support for hardware timestamp
Date: Tue, 30 Jun 2026 17:24:02 +0000 [thread overview]
Message-ID: <20260630172402.710D01F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260629-s2500-mac-phy-support-v6-6-18ce79500371@onsemi.com>
Thank you for your contribution! Sashiko AI review found 8 potential issue(s) to consider:
New issues:
- [Critical] Use-After-Free of `ongoing_tx_skb` due to premature timestamp processing.
- [High] Memory leak of SKBs in `tx_ts_skb_q` during device teardown and lost interrupts.
- [High] Unbounded queueing of TX timestamp SKBs leads to ID wrap-around and corrupt timestamp assignments.
- [High] Invalid pointer dereference of ERR_PTR during PTP clock teardown.
- [Medium] Packet corruption due to early return when disabling hardware timestamps.
- [Medium] Timestamp configuration state corruption on hardware programming failure.
Pre-existing issues:
- [High] A transient SKB allocation failure permanently disables the network interface (DoS).
- [High] Missing bounds check allows malformed MAC-PHY packets to trigger `skb_over_panic`.
--
commit 7f7731256fae07ec53c17aa75b9a25fc0f8b4a24
Author: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Subject: net: ethernet: oa_tc6: Support for hardware timestamp
This commit adds hardware timestamping support for the OPEN Alliance
10BASE-T1x MAC-PHY framework. It introduces PTP clock registration,
ioctl handling, and TX/RX packet timestamp extraction functions.
> diff --git a/drivers/net/ethernet/oa_tc6/oa_tc6.c b/drivers/net/ethernet/oa_tc6/oa_tc6.c
> index bf96e8d1ccb9a..6cc7c76d1d3c2 100644
> --- a/drivers/net/ethernet/oa_tc6/oa_tc6.c
> +++ b/drivers/net/ethernet/oa_tc6/oa_tc6.c
[ ... ]
> +static void oa_tc6_defer_for_hwtstamp(struct oa_tc6 *tc6,
> + struct sk_buff *skb)
> +{
> + if (!tc6->hw_tstamp_enabled)
> + return;
> + if (!skb || (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) == 0)
> + return;
> + if (tc6->ts_config.tx_type != HWTSTAMP_TX_ON) {
> + tc6->tx_hwtstamp_lost++;
> + return;
> + }
> +
> + skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
> + u8 ret = tc6->tx_ts_idx++;
[Severity: High]
Does this allow the hardware timestamp ID to wrap around and cause collisions?
The hardware provides only 3 TX timestamp IDs. In oa_tc6_defer_for_hwtstamp,
the code cyclically increments tsc from 1 to 3 and unconditionally adds the
socket buffer to tx_ts_skb_q without checking queue depth. If more than
3 timestamped packets are transmitted before an interrupt fires, the tsc
wraps around. When the interrupt eventually arrives,
oa_tc6_process_deferred_skb will process all buffers matching that tsc,
which could result in the same timestamp being assigned to multiple unrelated
packets.
> +
> + if (ret == OA_TC6_TTSCC_REG_ID)
> + tc6->tx_ts_idx = OA_TC6_TTSCA_REG_ID;
> + oa_tc6_tsinfo_tx(skb)->tsc = ret;
> +
> + list_add_tail(&skb->list, &tc6->tx_ts_skb_q);
> +}
> +
> +static int oa_tc6_process_deferred_skb(struct oa_tc6 *tc6, u8 tsc)
> +{
> + struct skb_shared_hwtstamps tstamp;
> + struct oa_tc6_ts_info_tx *ski;
> + struct sk_buff *skb, *tmp;
> + bool found = false;
> + int ret = 0;
[ ... ]
> + if (!ret) {
> + tstamp.hwtstamp = ktime_set(data[0], data[1]);
> + skb_tstamp_tx(skb, &tstamp);
> + tc6->tx_hwtstamp_pkts++;
> + }
> +
> + dev_kfree_skb(skb);
[Severity: Critical]
Is there a risk of a use-after-free on ongoing_tx_skb here?
If an skb is assigned to ongoing_tx_skb and placed into tx_ts_skb_q before
it is fully copied to the SPI TX buffer, a stale interrupt for an older
packet sharing the same tsc (due to the ID wrap-around mentioned earlier)
could arrive.
oa_tc6_process_deferred_skb would then unconditionally call dev_kfree_skb on
this buffer. The next iteration of the transmission loop in
oa_tc6_add_tx_skb_to_spi_buf would then dereference the freed ongoing_tx_skb
to continue transmitting its chunks.
> + }
> + return ret;
> +}
[ ... ]
> +static void oa_tc6_update_ts_in_rx_skb(struct oa_tc6 *tc6)
> +{
> + struct sk_buff *skb = tc6->rx_skb;
> + struct oa_tc6_ts_info_rx *ski;
> + __be32 ts_val[2];
> + u32 ts[2];
> +
> + if (!tc6->hw_tstamp_enabled)
> + return;
[Severity: Medium]
Could this leave corrupt hardware timestamp tags in the payload?
If the hardware was previously configured to append timestamps and the user
dynamically disables the feature via ioctl, in-flight packets will arrive
with ski->rtsa set. Because of this early return when hw_tstamp_enabled is
false, oa_tc6_update_ts_in_rx_skb skips stripping the 8-byte hardware
timestamp via skb_pull, which destroys the packet framing for the network
stack.
> + ski = oa_tc6_tsinfo_rx(skb);
> + if (!ski->rtsa)
> + return;
> +
> + memcpy(&ts_val[0], skb->data, 4);
[ ... ]
> -static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
> +static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6, u32 footer)
> {
> + struct oa_tc6_ts_info_rx *ski;
> +
> tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu +
> - ETH_HLEN + ETH_FCS_LEN);
> + ETH_HLEN + ETH_FCS_LEN + OA_TC6_TSTAMP_SZ);
> if (!tc6->rx_skb) {
> tc6->netdev->stats.rx_dropped++;
> return -ENOMEM;
[Severity: High]
This isn't a bug introduced by this patch, but does a transient memory
allocation failure permanently disable the interface?
If netdev_alloc_skb_ip_align fails under memory pressure, it returns -ENOMEM.
This error propagates up to the threaded IRQ handler
oa_tc6_macphy_threaded_irq, which explicitly checks for non-zero returns from
the rx path and calls disable_irq_nosync and oa_tc6_disable_traffic. This
permanently halts the interface instead of safely dropping the frame and
recovering.
> }
>
> + ski = oa_tc6_tsinfo_rx(tc6->rx_skb);
> + ski->rtsa = FIELD_GET(OA_TC6_DATA_FOOTER_RTSA_VALID, footer);
> + ski->rtsp = FIELD_GET(OA_TC6_DATA_FOOTER_RTSP_VALID, footer);
> return 0;
> }
[ ... ]
> @@ -831,13 +999,15 @@ static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length)
> /* Process the chunk with ongoing rx frame data */
> - oa_tc6_prcs_ongoing_rx_frame(tc6, data);
> + oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer);
[Severity: High]
This is a pre-existing issue, but is there a missing bounds check here that
could cause a panic?
If the hardware sends a continuous stream of data chunks without ever setting
the end_valid flag, the receive loop continuously appends 64 bytes using
skb_put in oa_tc6_prcs_ongoing_rx_frame. Without validating against the
available socket buffer tailroom, a broken or malicious MAC-PHY could exhaust
the buffer and trigger an skb_over_panic.
>
> return 0;
> }
[ ... ]
> @@ -1151,6 +1332,8 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
> SET_NETDEV_DEV(netdev, &spi->dev);
> mutex_init(&tc6->spi_ctrl_lock);
> spin_lock_init(&tc6->tx_skb_lock);
> + tc6->tx_ts_idx = OA_TC6_TTSCA_REG_ID;
> + INIT_LIST_HEAD(&tc6->tx_ts_skb_q);
[Severity: High]
Are the socket buffers in tx_ts_skb_q properly freed during device teardown?
When traffic is disabled or the device is torn down, it appears tx_ts_skb_q
is ignored by oa_tc6_free_pending_skbs. If an interrupt is lost, the buffers
remain in the queue forever, which could lead to a permanent memory leak of
the socket buffers and their associated references.
>
> /* Set the SPI controller to pump at realtime priority */
> tc6->spi->rt = true;
> diff --git a/drivers/net/ethernet/oa_tc6/oa_tc6_ptp.c b/drivers/net/ethernet/oa_tc6/oa_tc6_ptp.c
> new file mode 100644
> index 0000000000000..921191ec6829f
> --- /dev/null
> +++ b/drivers/net/ethernet/oa_tc6/oa_tc6_ptp.c
[ ... ]
> +int oa_tc6_ptp_register(struct oa_tc6 *tc6, struct ptp_clock_info *info)
> +{
> + /* Not supporting hardware timestamp isn't an error */
> + if (!tc6->hw_tstamp_supported)
> + return 0;
> +
> + snprintf(info->name, sizeof(info->name), "%s",
> + "OA TC6 PTP clock");
> + tc6->ptp_clock = ptp_clock_register(info, &tc6->spi->dev);
> + if (IS_ERR(tc6->ptp_clock)) {
> + dev_err(&tc6->spi->dev, "Registration of %s failed",
> + info->name);
> + return -EFAULT;
> + }
[Severity: High]
Can this cause an invalid pointer dereference on cleanup?
If ptp_clock_register fails, it returns an ERR_PTR which is stored directly
in tc6->ptp_clock. The function returns an error without resetting the
pointer to NULL. Later, oa_tc6_ptp_unregister checks if tc6->ptp_clock is
true, which it is for an ERR_PTR, and attempts to unregister it, leading to a
panic.
> + dev_info(&tc6->spi->dev, "%s registered. index %d", info->name,
> + ptp_clock_index(tc6->ptp_clock));
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(oa_tc6_ptp_register);
[ ... ]
> diff --git a/drivers/net/ethernet/oa_tc6/oa_tc6_tstamp.c b/drivers/net/ethernet/oa_tc6/oa_tc6_tstamp.c
> new file mode 100644
> index 0000000000000..272701a4081dc
> --- /dev/null
> +++ b/drivers/net/ethernet/oa_tc6/oa_tc6_tstamp.c
[ ... ]
> +int oa_tc6_hwtstamp_set(struct oa_tc6 *tc6,
> + struct kernel_hwtstamp_config *cfg)
> +{
[ ... ]
> + hwtstamp_config_from_kernel(&tc6->ts_config, cfg);
> +
> + /* Supports timestamping all traffic */
> + if (cfg->rx_filter != HWTSTAMP_FILTER_NONE)
> + tc6->ts_config.rx_filter = HWTSTAMP_FILTER_ALL;
> + return oa_tc6_set_hwtstamp_settings(tc6);
[Severity: Medium]
Does this leave the timestamp configuration in an inconsistent state if
hardware programming fails?
The driver copies the new configuration into tc6->ts_config before calling
oa_tc6_set_hwtstamp_settings to program the hardware via SPI. If the SPI
transfer fails, the function returns an error, but tc6->ts_config remains
overwritten with the new values. Future queries to the timestamp
configuration will falsely report the failed configuration.
> +}
> +EXPORT_SYMBOL_GPL(oa_tc6_hwtstamp_set);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260629-s2500-mac-phy-support-v6-0-18ce79500371@onsemi.com?part=6
next prev parent reply other threads:[~2026-06-30 17:24 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-29 17:23 [PATCH net-next v6 00/15] Support for onsemi's S2500 10Base-T1S MAC-PHY Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 01/15] net: phy: Helper to read and write through C45 without lock Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 02/15] net: phy: Helper to modify PHY loopback mode only Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 03/15] net: ethernet: oa_tc6: Move oa_tc6.c to its own directory Selvamani Rajagopal via B4 Relay
2026-06-30 17:24 ` sashiko-bot
2026-06-29 17:23 ` [PATCH net-next v6 04/15] net: phy: microchip_t1s: Use generic APIs for C45 read and write Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 05/15] net: ethernet: oa_tc6: Move constant definitions to header file Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 06/15] net: ethernet: oa_tc6: Support for hardware timestamp Selvamani Rajagopal via B4 Relay
2026-06-30 17:24 ` sashiko-bot [this message]
2026-07-01 19:33 ` Jerry.Ray
2026-07-01 21:59 ` Selvamani Rajagopal
2026-06-29 17:23 ` [PATCH net-next v6 07/15] net: ethernet: oa_tc6: Support for vendor specific MMS Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 08/15] net: ethernet: oa_tc6: read, write interface with MMS option Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 09/15] net: phy: ncn26000: Support for onsemi's S2500 internal phy Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 10/15] net: phy: ncn26000: Enable enhanced noise immunity Selvamani Rajagopal via B4 Relay
2026-06-29 17:23 ` [PATCH net-next v6 11/15] net: phy: ncn26000: Support for loopback Selvamani Rajagopal via B4 Relay
2026-06-30 17:24 ` sashiko-bot
2026-06-29 17:23 ` [PATCH net-next v6 12/15] onsemi: s2500: Add driver support for TS2500 MAC-PHY Selvamani Rajagopal via B4 Relay
2026-06-30 17:08 ` Uwe Kleine-König
2026-06-30 17:36 ` Selvamani Rajagopal
2026-06-30 17:24 ` sashiko-bot
2026-06-29 17:23 ` [PATCH net-next v6 13/15] onsemi: s2500: Added selftest support to onsemi's S2500 driver Selvamani Rajagopal via B4 Relay
2026-06-30 17:24 ` sashiko-bot
2026-06-29 17:23 ` [PATCH net-next v6 14/15] dt-bindings: net: add onsemi's S2500 Selvamani Rajagopal via B4 Relay
2026-06-30 6:29 ` Krzysztof Kozlowski
2026-06-30 15:09 ` Selvamani Rajagopal
2026-06-30 17:24 ` sashiko-bot
2026-06-29 17:23 ` [PATCH net-next v6 15/15] Documentation: networking: Add timestamp related APIs to OA TC6 framework Selvamani Rajagopal via B4 Relay
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=20260630172402.710D01F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=devnull+Selvamani.Rajagopal.onsemi.com@kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox