All of lore.kernel.org
 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: 17+ 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 ` Oliver Hartkopp
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:42   ` Oliver Hartkopp
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:42   ` Oliver Hartkopp
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:42   ` Oliver Hartkopp
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:42   ` Oliver Hartkopp
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:42   ` Oliver Hartkopp
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 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.