Linux CAN drivers development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Oliver Hartkopp" <socketcan@hartkopp.net>
Cc: "Marc Kleine-Budde" <mkl@pengutronix.de>,
	"Oliver Hartkopp" <socketcan@hartkopp.net>,
	"Vincent Mailhol" <mailhol@kernel.org>,
	"Oleksij Rempel" <o.rempel@pengutronix.de>,
	linux-can@vger.kernel.org
Subject: Re: [PATCH v6 3/5] can: isotp: fix race between RX/TX timers and frame reception
Date: Fri, 10 Jul 2026 20:55:20 +0000	[thread overview]
Message-ID: <20260710205521.6D0A71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260710-isotp-fixes-v6-3-a13c2539093d@hartkopp.net>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] Moving `so->tx.state = ISOTP_IDLE` after `hrtimer_cancel()` in the `err_event_drop` path introduces a race condition with softirq receive handlers, leading to stray timers that can corrupt subsequent transmissions.
- [High] The delayed `so->tx.state = ISOTP_IDLE` assignment in the error path unconditionally clobbers the state, which can corrupt a new, concurrently running transfer.
- [High] The newly added TX state checks after `hrtimer_cancel()` in `isotp_rcv_fc()` and `isotp_rcv_echo()` are vulnerable to an ABA race condition, allowing stale frames to corrupt new transfers.

Pre-existing issues:
- [High] Missing cleanup of `so->cfecho` in `isotp_sendmsg()` error paths allows stale local echoes to corrupt subsequent transfers.
--

--- Patch [3]: [PATCH v6 3/5] can: isotp: fix race between RX/TX timers and frame reception ---
commit 4f481801d9d9059ae72ceaf6467d32f307eddbb5
Author: Oliver Hartkopp <socketcan@hartkopp.net>
can: isotp: fix race between RX/TX timers and frame reception

This patch fixes a race condition between hrtimer execution and frame
reception by checking the state after hrtimer_cancel(). It also reorders
timer cancellation and state reset in isotp_sendmsg()'s error path to
prevent concurrent sendmsg calls from corrupting state.

Link: https://lore.kernel.org/linux-can/20260710142146.BDAE61F000E9@smtp.kernel.org/

> diff --git a/net/can/isotp.c b/net/can/isotp.c
> index 44c044eb83e12..5ef2a610fc172 100644
> --- a/net/can/isotp.c
> +++ b/net/can/isotp.c
[ ... ]
> @@ -378,6 +378,15 @@ static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
>  
>  	hrtimer_cancel(&so->txtimer);
>  
> +	/* isotp_tx_timer_handler() may have raced us for so->tx.state while
> +	 * hrtimer_cancel() above waited for it to finish, already reporting
> +	 * the tx error and resetting the state; don't resume a tx job that
> +	 * has already been given up on.
> +	 */
> +	if (so->tx.state != ISOTP_WAIT_FC &&
> +	    so->tx.state != ISOTP_WAIT_FIRST_FC)
> +		return 1;
> +

[Severity: High]
Is this lockless state check vulnerable to an ABA transition?

While hrtimer_cancel() spins waiting for a timer handler, the timer handler
could reset the state to ISOTP_IDLE. If a concurrent isotp_sendmsg() from
another thread starts a new transfer during this window, it could locklessly
transition the state back to the exact same expected state
(e.g., ISOTP_WAIT_FIRST_FC).

When hrtimer_cancel() returns, this check would pass because the state
matches, but it would be evaluating a different transfer. Could this allow a
stale Flow Control frame to corrupt the new transfer?

[ ... ]
> @@ -881,6 +898,14 @@ static void isotp_rcv_echo(struct sk_buff *skb, void *data)
>  	/* local echo skb with consecutive frame has been consumed */
>  	so->cfecho = 0;
>  
> +	/* isotp_tx_timer_handler() may have raced us for so->tx.state while
> +	 * hrtimer_cancel() above waited for it to finish, already reporting
> +	 * the tx error and resetting the state; don't resume a tx job that
> +	 * has already been given up on.
> +	 */
> +	if (so->tx.state != ISOTP_SENDING)
> +		return;
> +

[Severity: High]
Could the same ABA race happen here?

If a timer resets the state to ISOTP_IDLE while hrtimer_cancel() waits,
and a concurrent isotp_sendmsg() starts a new transfer and sets the state to
ISOTP_SENDING, this check would pass for the new transfer.

Would this allow a stale local echo to erroneously resume the newly started
transfer?

[ ... ]
> @@ -1143,8 +1168,7 @@ static int isotp_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
>  	return size;
>  
>  err_event_drop:
> -	/* got signal: force tx state machine to be idle */
> -	so->tx.state = ISOTP_IDLE;
> +	/* got signal: force tx state machine to be ISOTP_IDLE */
>  	hrtimer_cancel(&so->txfrtimer);
>  	hrtimer_cancel(&so->txtimer);
>  err_out_drop:

[Severity: High]
Does delaying the state reset to after hrtimer_cancel() create a window
where concurrent RX softirqs can observe an active state?

If isotp_sendmsg() is interrupted by a signal, it now calls
hrtimer_cancel() while so->tx.state is still visibly active
(e.g., ISOTP_SENDING). If a CAN receive handler (like isotp_rcv_echo())
executes concurrently in softirq context, it locklessly checks
so->tx.state, sees it is active, and can re-arm the transmission timers.

When this error path completes, it sets the state to ISOTP_IDLE, leaving
the newly armed timers active. When a subsequent sendmsg() begins, could
these stray timers fire unexpectedly and corrupt the new transfer's
sequence?

[Severity: High]
Does the delayed assignment of ISOTP_IDLE in err_out_drop clobber
concurrently claimed state?

While hrtimer_cancel() waits for a timer handler to finish (which resets
the state to ISOTP_IDLE), a concurrent thread could call isotp_sendmsg(),
successfully claim the ISOTP_IDLE state, and begin a new transfer.

When the original thread finishes hrtimer_cancel(), it unconditionally
executes so->tx.state = ISOTP_IDLE (located under err_out_drop:). Could
this abruptly clobber the new transfer's state and expose its buffer to
concurrent overwrites?

[Severity: High]
This is a pre-existing issue, but does the error path fail to clean up
so->cfecho?

If a transmission is aborted via a signal, the state is forced to
ISOTP_IDLE but so->cfecho is not cleared and continues to hold the local
echo tag of the aborted frame.

When a subsequent sendmsg() sets the state to ISOTP_SENDING and begins
preparing the buffer, a stale echo could arrive. If isotp_rcv_echo() sees
a matching so->cfecho and an active ISOTP_SENDING state, could it process
the echo and initiate a transmission containing uninitialized heap data?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260710-isotp-fixes-v6-0-a13c2539093d@hartkopp.net?part=3

  reply	other threads:[~2026-07-10 20:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10 20:42 [PATCH v6 0/5] net: can: isotp-fixes Oliver Hartkopp via B4 Relay
2026-07-10 20:42 ` [PATCH v6 1/5] can: isotp: use unconditional synchronize_rcu() in isotp_release() Oliver Hartkopp via B4 Relay
2026-07-10 20:58   ` sashiko-bot
2026-07-10 20:42 ` [PATCH v6 2/5] can: isotp: fix use-after-free race with concurrent NETDEV_UNREGISTER Oliver Hartkopp via B4 Relay
2026-07-10 20:56   ` sashiko-bot
2026-07-10 20:42 ` [PATCH v6 3/5] can: isotp: fix race between RX/TX timers and frame reception Oliver Hartkopp via B4 Relay
2026-07-10 20:55   ` sashiko-bot [this message]
2026-07-10 20:42 ` [PATCH v6 4/5] can: isotp: fix lock-free state transition in tx timer handler Oliver Hartkopp via B4 Relay
2026-07-10 20:57   ` sashiko-bot
2026-07-10 20:42 ` [PATCH v6 5/5] can: isotp: fix state machine corruption on signal interruption Oliver Hartkopp via B4 Relay
2026-07-10 20:52   ` sashiko-bot

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=20260710205521.6D0A71F000E9@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox