Re: [PATCH v2 2/3] can: rockchip_canfd: retry the outstanding TX buffer
[email protected] Thu, 30 Jul 2026 10:34:38 +0000
| Newsgroups | org.kernel.vger.linux-can |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 1 potential issue(= s) to consider: Pre-existing issues: - [High] TOCTOU race in `rkcanfd_tx_tail_is_eff()` causes spurious NULL poi= nter errors in the kernel log and a Use-After-Free vulnerability. -- --- Patch [2]: [PATCH v2 2/3] can: rockchip_canfd: retry the outstanding TX= buffer --- commit 5e421e7397d8c64fe895d386c02cbed045a1e541 Author: Cunhao Lu <[email protected]> can: rockchip_canfd: retry the outstanding TX buffer rkcanfd_xmit_retry() originally operated with a TX FIFO depth of one. At that depth, the masked head and tail indices both select buffer 0, so using tx_head happened to select the correct buffer. After the FIFO depth was increased to two, tx_head instead identifies the next free buffer when one frame is outstanding. The erratum 6 workaround therefore requests transmission from the wrong buffer, leaving the outstanding echo entry incomplete and the netdev TX queue stopped. Use tx_tail to select the outstanding buffer for retransmission. > diff --git a/drivers/net/can/rockchip/rockchip_canfd-tx.c b/drivers/net/c= an/rockchip/rockchip_canfd-tx.c > index d2cbe25c46d6c..c4ecdc9411cc6 100644 > --- a/drivers/net/can/rockchip/rockchip_canfd-tx.c > +++ b/drivers/net/can/rockchip/rockchip_canfd-tx.c > @@ -57,8 +57,8 @@ static void rkcanfd_start_xmit_write_cmd(const struct r= kcanfd_priv *priv, > =20 > void rkcanfd_xmit_retry(struct rkcanfd_priv *priv) > { > - const unsigned int tx_head =3D rkcanfd_get_tx_head(priv); > - const u32 reg_cmd =3D RKCANFD_REG_CMD_TX_REQ(tx_head); > + const unsigned int tx_tail =3D rkcanfd_get_tx_tail(priv); > + const u32 reg_cmd =3D RKCANFD_REG_CMD_TX_REQ(tx_tail); > =20 > rkcanfd_start_xmit_write_cmd(priv, reg_cmd); > } [Severity: High] This is a pre-existing issue, but does the lockless access to tx_tail and echo_skb in rkcanfd_tx_tail_is_eff() introduce a race condition? drivers/net/can/rockchip/rockchip_canfd-tx.c:rkcanfd_tx_tail_is_eff() { ... tx_tail =3D rkcanfd_get_tx_tail(priv); skb =3D priv->can.echo_skb[tx_tail]; if (!skb) { netdev_err(priv->ndev, "%s: echo_skb[%u]=3DNULL tx_head=3D0x%08x tx_tail=3D0x%08x\n", __func__, tx_tail, priv->tx_head, priv->tx_tail); return false; } cfd =3D (struct canfd_frame *)skb->data; return cfd->can_id & CAN_EFF_FLAG; } The transmit path holds netif_tx_lock, which disables softirqs but leaves hardirqs enabled. If a hardware RX interrupt fires concurrently, it can process the loopback frame, free the echo_skb (setting it to NULL), and increment tx_tail. If the interrupt fires between reading tx_tail and accessing the array, could this read NULL and spuriously flood the kernel log with netdev_err? If the interrupt fires after the skb pointer is read but before skb->data is accessed, could the SKB be freed before it is used, leading to a use-after-free when evaluating cfd->can_id & CAN_EFF_FLAG? --=20 Sashiko AI review =C2=B7 https://sashiko.dev/#/patchset/20260730-master-v2-= [email protected]?part=3D2