From: sashiko-bot@kernel.org
To: "Felix Hoffmann" <f3lix.dev@gmx.de>
Cc: "Oliver Hartkopp" <socketcan@hartkopp.net>,
"Vincent Mailhol" <mailhol@kernel.org>,
linux-can@vger.kernel.org,
"Oleksij Rempel" <o.rempel@pengutronix.de>,
"Marc Kleine-Budde" <mkl@pengutronix.de>
Subject: Re: [PATCH can v2] can: j1939: avoid address-claim timer deadlock
Date: Mon, 03 Aug 2026 10:43:24 +0000 [thread overview]
Message-ID: <20260803104325.C2E3E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260803101503.21023-1-f3lix.dev@gmx.de>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Lockless calls to `j1939_ecu_put()` can drop the last reference to an ECU, triggering `__j1939_ecu_release()` and modifying `priv->ecus` locklessly.
- [High] Permanent memory leak of `j1939_ecu` and `j1939_priv` when the network interface is brought down while an address claim timer is pending.
--
--- Patch [1]: [PATCH can v2] can: j1939: avoid address-claim timer deadlock ---
commit 08d11140bccb342c8267ab26aee9e24877e324a3
Author: Felix Hoffmann <f3lix.dev@gmx.de>
can: j1939: avoid address-claim timer deadlock
j1939_ac_process() holds priv->lock while synchronously canceling an
ECU's address-claim hrtimer. The timer callback takes the same lock. If the
callback starts on another CPU after the receive path takes the lock, the
callback waits for priv->lock while hrtimer_cancel() waits for the callback
to finish. This deadlocks both CPUs and makes the system unresponsive.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Hoffmann <f3lix.dev@gmx.de>
> diff --git a/net/can/j1939/bus.c b/net/can/j1939/bus.c
> index cdc3c0a719379..eb9a3fd847f42 100644
> --- a/net/can/j1939/bus.c
> +++ b/net/can/j1939/bus.c
> @@ -10,10 +10,19 @@
> * Since rtnetlink, no real bus is used.
> */
>
> +#include <linux/net.h>
> +
> #include <net/sock.h>
>
> #include "j1939-priv.h"
>
> +#define J1939_ECU_TIMER_RETRY_DELAY_MS 1
> +/*
> + * J1939 does not specify a lock-contention retry count. Five retries are a
> + * pragmatic threshold for warning about an unusual address-claim delay.
> + */
> +#define J1939_ECU_TIMER_RETRY_WARN 5
> +
> static void __j1939_ecu_release(struct kref *kref)
> {
> struct j1939_ecu *ecu = container_of(kref, struct j1939_ecu, kref);
> struct j1939_priv *priv = ecu->priv;
>
> list_del(&ecu->list);
[Severity: High]
This isn't a bug introduced by this patch, but could this lead to list
corruption?
If an ECU is concurrently unmapped (dropping its primary reference) while
another thread holds a temporary reference (e.g., in j1939_ac_recv() or
j1939_ac_fixup()), dropping the temporary reference locklessly via
j1939_ecu_put() will reduce the refcount to 0.
This triggers __j1939_ecu_release(), which performs list_del(&ecu->list) on
priv->ecus without holding priv->lock.
Can this be triggered remotely by sending precisely timed address claim and
release packets to cause a use-after-free or panic?
[ ... ]
> @@ -109,6 +118,8 @@ void j1939_ecu_unmap_all(struct j1939_priv *priv)
>
> void j1939_ecu_timer_start(struct j1939_ecu *ecu)
> {
[Severity: High]
This is a pre-existing issue, but does this leak j1939_ecu and j1939_priv when
the network interface is brought down?
When a J1939 interface is unregistered, j1939_ecu_unmap_all() clears mapped
ECUs from priv->ents, but it only iterates over mapped ECUs and ignores ECUs
in priv->ecus that have a pending timer:
net/can/j1939/bus.c:j1939_ecu_unmap_all() {
for (i = 0; i < ARRAY_SIZE(priv->ents); i++)
if (priv->ents[i].ecu)
j1939_ecu_unmap_locked(priv->ents[i].ecu);
}
It seems this fails to cancel pending ac_timer hrtimers for ECUs in the
middle of address claiming.
When the uncancelled timer subsequently fires, j1939_ecu_timer_handler()
executes and maps the ECU back into the now-abandoned j1939_priv.
Since interface teardown (j1939_netdev_notify()) won't run
j1939_ecu_unmap_all() again, does this cause a permanent leak blocking
unregister_netdevice()?
> + ecu->ac_timer_retries = 0;
> +
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260803101503.21023-1-f3lix.dev@gmx.de?part=1
next prev parent reply other threads:[~2026-08-03 10:43 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-31 13:42 [PATCH net] can: j1939: avoid address-claim timer deadlock Felix Hoffmann
2026-08-01 13:43 ` sashiko-bot
2026-08-03 6:18 ` Oleksij Rempel
2026-08-03 10:15 ` [PATCH can v2] " Felix Hoffmann
2026-08-03 10:43 ` sashiko-bot [this message]
2026-08-04 7:12 ` Oleksij Rempel
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=20260803104325.C2E3E1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=f3lix.dev@gmx.de \
--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