All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Tetsuo Handa" <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: "Oleksij Rempel" <o.rempel@pengutronix.de>,
	"Oliver Hartkopp" <socketcan@hartkopp.net>,
	linux-can@vger.kernel.org, "Vincent Mailhol" <mailhol@kernel.org>,
	"Marc Kleine-Budde" <mkl@pengutronix.de>
Subject: Re: [PATCH v2] can: j1939: cancel pending address claim timers on rx release
Date: Tue, 29 Sep 2026 10:40:03 +0000	[thread overview]
Message-ID: <20260929104003.C258B1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <853e770e-4eee-4da8-8cf0-08731f9651ab@I-love.SAKURA.ne.jp>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] can: j1939: list corruption via lockless j1939_ecu_put()
--

commit 0dc29971aa78a56ec257a9c34f0e743a7e1b0390
Author: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>

can: j1939: cancel pending address claim timers on rx release

This commit attempts to fix a struct j1939_ecu refcount leak by cancelling
address claim timers before calling j1939_ecu_unmap_all() during device
teardown. It adds a rescan loop in __j1939_rx_release() to safely cancel
timers while avoiding deadlocks.

Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260928193312.553632-1-mkl%40pengutronix.de

> diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c
> index 5e5e6c228f225..3a4de839cf9a2 100644
> --- a/net/can/j1939/main.c
> +++ b/net/can/j1939/main.c

[ ... ]

> @@ -212,8 +212,38 @@ static void __j1939_rx_release(struct kref *kref)
>  {
>  	struct j1939_priv *priv = container_of(kref, struct j1939_priv,
>  					       rx_kref);
> +	struct j1939_ecu *ecu;
>  
>  	j1939_can_rx_unregister(priv);
> +
> +	/* can_rx_unregister() uses call_rcu() internally and is asynchronous.
> +	 * We must wait for an RCU grace period to ensure that any in-flight
> +	 * j1939_can_recv() instances on other CPUs have fully completed.
> +	 */
> +	synchronize_rcu();
> +
> +	/* Cancel all pending address claim timers before unmapping the ECUs.
> +	 * This prevents an orphaned timer from re-mapping an ECU after the
> +	 * rx path has been completely torn down.
> +	 */
> +rescan_timers:
> +	write_lock_bh(&priv->lock);
> +	list_for_each_entry(ecu, &priv->ecus, list) {
> +		int ret = hrtimer_try_to_cancel(&ecu->ac_timer);
> +
> +		if (ret == 0) /* Was not running. */
> +			continue;
> +		kref_get(&ecu->kref);
> +		write_unlock_bh(&priv->lock);
> +		if (ret == -1) /* Was running. Wait without lock. */
> +			j1939_ecu_timer_cancel(ecu);
> +		else /* Was canceled. Drop ref from j1939_ecu_timer_start(). */
> +			j1939_ecu_put(ecu);
> +		j1939_ecu_put(ecu);

[Severity: High]
Could these lockless j1939_ecu_put() calls trigger list corruption?

When __j1939_rx_release() cancels the timer, it drops priv->lock before
dropping the references. If this ecu's reference count drops to zero here
(for example, if the timer was the last reference), __j1939_ecu_release() 
will run locklessly.

Looking at __j1939_ecu_release() in net/can/j1939/bus.c, it modifies the 
list without acquiring priv->lock:

net/can/j1939/bus.c:__j1939_ecu_release() {
    ...
    list_del(&ecu->list);
    ...
}

Does this deterministic path lead to a kernel panic when other threads traverse
or modify priv->ecus during device teardown?

As an aside, looking at j1939_ac_recv() in net/can/j1939/address-claim.c, it
has a pre-existing example of dropping a reference locklessly. Is it possible 
that the underlying list deletion vulnerability exists elsewhere as well?

> +		goto rescan_timers;
> +	}
> +	write_unlock_bh(&priv->lock);
> +
>  	j1939_ecu_unmap_all(priv);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/853e770e-4eee-4da8-8cf0-08731f9651ab@I-love.SAKURA.ne.jp?part=1

      reply	other threads:[~2026-09-29 10:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29 10:25 [PATCH v2] can: j1939: cancel pending address claim timers on rx release Tetsuo Handa
2026-09-29 10:40 ` 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=20260929104003.C258B1F000FF@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=penguin-kernel@I-love.SAKURA.ne.jp \
    --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.