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 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.