From: sashiko-bot@kernel.org
To: "Oliver Hartkopp" <socketcan@hartkopp.net>
Cc: "Marc Kleine-Budde" <mkl@pengutronix.de>,
linux-can@vger.kernel.org,
"Oliver Hartkopp" <socketcan@hartkopp.net>,
"Vincent Mailhol" <mailhol@kernel.org>,
"Oleksij Rempel" <o.rempel@pengutronix.de>
Subject: Re: [PATCH v2] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering
Date: Mon, 20 Jul 2026 14:09:46 +0000 [thread overview]
Message-ID: <20260720140946.A91E71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260720135701.124633-1-socketcan@hartkopp.net>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] A stale local echo from an interrupted transfer can prematurely complete a new transfer if their first 3 payload bytes match.
- [Medium] Missing READ_ONCE()/WRITE_ONCE() for lock-free accesses to `so->cfecho` causes data races.
--
--- Patch [1]: [PATCH v2] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering ---
commit f9db7885e3deec5f74c17326758f7a0025ece72d
Author: Oliver Hartkopp <socketcan@hartkopp.net>
can: isotp: fix timer drain order, wakeup handling and tx_gen ordering
This patch is a follow-up to commit cf070fe33bfb ("can: isotp: serialize
TX state transitions under so->rx_lock") which addresses following
sashiko-bot findings:
[ ... ]
> diff --git a/net/can/isotp.c b/net/can/isotp.c
> index 54becaf6898f1..ff6299f5c4a0b 100644
> --- a/net/can/isotp.c
> +++ b/net/can/isotp.c
> @@ -899,32 +901,32 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
> spin_lock(&so->rx_lock);
>
> /* so->cfecho may since belong to a new transfer; recheck under lock */
> - if (so->cfecho != *(u32 *)cf->data)
> + if (READ_ONCE(so->cfecho) != *(u32 *)cf->data)
> goto out_unlock;
[Severity: High]
This is a pre-existing issue, but can a stale local echo prematurely complete
a new transfer if their first 4 payload bytes match?
If a transmission (SF or CF-broadcast) is interrupted by a signal,
isotp_sendmsg() cancels timers, sets the state to IDLE, and returns, leaving
a pending loopback echo in the network queue.
If the user immediately retries sendmsg with the exact same payload, won't
this stale echo be processed by isotp_rcv_echo() and match the new so->cfecho
tag, since the tag is derived solely from the first 4 bytes of the CAN frame?
This seems like it could cause the sender to falsely believe the transfer is
complete while it may still be in progress, violating the
CAN_ISOTP_WAIT_TX_DONE guarantee.
>
> /* cancel local echo timeout */
> hrtimer_cancel(&so->echotimer);
>
> /* local echo skb with consecutive frame has been consumed */
> - so->cfecho = 0;
> + WRITE_ONCE(so->cfecho, 0);
[ ... ]
> @@ -1046,29 +1052,32 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
> if (msg->msg_flags & MSG_DONTWAIT)
> return -EAGAIN;
>
> - if (so->tx.state == ISOTP_SHUTDOWN)
> + if (READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN)
> return -EADDRNOTAVAIL;
>
> /* wait for complete transmission of current pdu */
> err = wait_event_interruptible(so->wait,
> - so->tx.state == ISOTP_IDLE);
> + READ_ONCE(so->tx.state) == ISOTP_IDLE ||
> + READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN);
> if (err)
> return err;
> }
>
> - /* new transfer: bump so->tx_gen and drain the old one's timers,
> - * still under the so->rx_lock we just claimed the socket with
> - */
> - WRITE_ONCE(so->tx.state, ISOTP_SENDING);
> - WRITE_ONCE(so->tx_gen, READ_ONCE(so->tx_gen) + 1);
> + /* txfrtimer's callback re-arms echotimer lock-free: drain it first */
> + hrtimer_cancel(&so->txfrtimer);
> hrtimer_cancel(&so->txtimer);
> hrtimer_cancel(&so->echotimer);
> - hrtimer_cancel(&so->txfrtimer);
> - so->cfecho = 0;
> +
> + /* new transfer: increment so->tx_gen and set tx.state after barrier */
> + my_gen = READ_ONCE(so->tx_gen) + 1;
> + WRITE_ONCE(so->tx_gen, my_gen);
> + smp_wmb(); /* pairs with the cmpxchg() in isotp_tx_timeout() */
> + WRITE_ONCE(so->tx.state, ISOTP_SENDING);
> + WRITE_ONCE(so->cfecho, 0);
[Severity: Medium]
This is a pre-existing issue, but does this miss some READ_ONCE() and
WRITE_ONCE() annotations for lock-free accesses to so->cfecho in
isotp_sendmsg() and isotp_bind()?
While the patch aligns many accesses, isotp_sendmsg() sets the transmission
state to ISOTP_SENDING before so->cfecho is initialized and written for
SF-mode and CF-broadcast. Because the state is already ISOTP_SENDING, a
concurrently arriving stale echo can trigger isotp_rcv_echo(), which reads
so->cfecho via READ_ONCE().
However, isotp_sendmsg() still performs plain reads and writes later in the
function:
if (so->cfecho)
pr_notice_once("can-isotp: uninit cfecho %08X\n", so->cfecho);
/* ... */
so->cfecho = *(u32 *)cf->data;
Similarly, isotp_bind() performs a plain write to so->cfecho = 0; while
isotp_rcv_echo() could still be processing an in-flight echo.
Could this lead to data races or torn reads?
> spin_unlock_bh(&so->rx_lock);
>
> /* so->bound is only checked once above - a wakeup may have
> - * unbound/rebound the socket meanwhile, so re-validate it
> + * unbound/rebound the socket meanwhile => recheck
> */
> if (!so->bound) {
> err = -EADDRNOTAVAIL;
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260720135701.124633-1-socketcan@hartkopp.net?part=1
prev parent reply other threads:[~2026-07-20 14:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-20 13:57 [PATCH v2] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering Oliver Hartkopp
2026-07-20 14:09 ` 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=20260720140946.A91E71F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-can@vger.kernel.org \
--cc=mailhol@kernel.org \
--cc=mkl@pengutronix.de \
--cc=o.rempel@pengutronix.de \
--cc=sashiko-reviews@lists.linux.dev \
--cc=socketcan@hartkopp.net \
/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.