From: sashiko-bot@kernel.org
To: "Tetsuo Handa" <penguin-kernel@I-love.SAKURA.ne.jp>,
linux-can@vger.kernel.org
Cc: "Marc Kleine-Budde" <mkl@pengutronix.de>,
"Oliver Hartkopp" <socketcan@hartkopp.net>,
"Vincent Mailhol" <mailhol@kernel.org>,
"Oleksij Rempel" <o.rempel@pengutronix.de>
Subject: Re: [PATCH v13 1/6] can: j1939: fix possibility of UAF on module unload
Date: Sun, 15 Nov 2026 06:01:07 +0000 [thread overview]
Message-ID: <sashiko-outbox-215239@kernel.org> (raw)
In-Reply-To: <1e3283a1-82f4-42c4-874a-96db238d25e4@I-love.SAKURA.ne.jp>
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] can: j1939: premature module_put() in
__j1939_priv_release_work()
--
commit 9938b84eee258ec84033c319ff76028286604caa
Author: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
can: j1939: fix possibility of UAF on module unload
This commit ties a module reference to each struct j1939_priv and defers
its final release to a dedicated workqueue that is destroyed in
j1939_module_exit().
> diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c
> index d9384cf0e356f..0b8ac4fe0479d 100644
> --- a/net/can/j1939/main.c
> +++ b/net/can/j1939/main.c
[ ... ]
> @@ -152,9 +159,9 @@ static inline void j1939_priv_set(struct net_device *ndev,
> can_ml->j1939_priv = priv;
> }
>
> -static void __j1939_priv_release(struct kref *kref)
> +static void __j1939_priv_release_work(struct work_struct *work)
> {
> - struct j1939_priv *priv = container_of(kref, struct j1939_priv, kref);
> + struct j1939_priv *priv = container_of(work, struct j1939_priv, release_work);
> struct net_device *ndev = priv->ndev;
>
> netdev_dbg(priv->ndev, "%s: 0x%p\n", __func__, priv);
> @@ -165,6 +172,22 @@ static void __j1939_priv_release(struct kref *kref)
>
> netdev_put(ndev, &priv->dev_tracker);
> kfree(priv);
> + /* This is safe, for j1939_module_exit() waits for completion of
> + * this callback using destroy_workqueue().
> + */
> + module_put(THIS_MODULE);
> +}
> +
> +static void __j1939_priv_release(struct kref *kref)
> +{
> + struct j1939_priv *priv = container_of(kref, struct j1939_priv, kref);
> +
> + /* Since synchronously dropping module refcount of self is not safe,
> + * defer actual release to WQ context.
> + */
> + INIT_WORK(&priv->release_work, __j1939_priv_release_work);
> + queue_work(j1939_wq, &priv->release_work);
> +
> }
[Severity: Medium]
Can __j1939_priv_release_work() drop the final module reference and allow
can-j1939 to be unmapped before the caller of j1939_priv_put() has finished
executing module code?
Later patches in this series defer struct j1939_ecu destruction to
j1939_wq, but struct j1939_session destruction remains synchronous. An RX
session created by j1939_xtp_rx_rts_session_new() has no associated socket
and holds a reference to priv, so it can outlive all J1939 sockets. When
its timer expires, j1939_session_destroy() drops the last reference to
priv before freeing the session and returning:
net/can/j1939/transport.c:j1939_session_destroy() {
...
__j1939_session_drop(session);
netdev_put(session->priv->ndev, &session->priv_dev_tracker);
j1939_priv_put(session->priv);
kfree(session);
}
Because j1939_wq is a WQ_HIGHPRI workqueue and destroy_workqueue(j1939_wq)
only waits for work items on j1939_wq, the module can be unloaded while
the timer callback is still unwinding:
CPU0 CPU1
j1939_tp_rxtimer()
j1939_session_put()
j1939_session_destroy()
j1939_priv_put()
__j1939_priv_release()
queue_work(j1939_wq, ...)
[preempted]
__j1939_priv_release_work()
kfree(priv)
module_put(THIS_MODULE)
delete_module()
j1939_module_exit()
destroy_workqueue(j1939_wq)
free_module()
kfree(session) <-- executes unmapped module text
Deferring session destruction (or the j1939_priv_put() call in
j1939_session_destroy()) to j1939_wq as well would ensure
destroy_workqueue(j1939_wq) waits for all module code paths to finish.
--
Sashiko AI review · https://sashiko.dev/#/patchset/7cc08b0f-290e-464b-ab13-0a5ce3c57f4f@I-love.SAKURA.ne.jp?part=1
next prev parent reply other threads:[~2026-11-15 6:01 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-15 5:34 [PATCH v13 0/6] can: j1939: make module more robust Tetsuo Handa
2026-11-15 5:34 ` [PATCH v13 1/6] can: j1939: fix possibility of UAF on module unload Tetsuo Handa
2026-11-15 6:01 ` sashiko-bot [this message]
2026-11-15 5:34 ` [PATCH v13 2/6] can: j1939: add a safeguard to __j1939_priv_release_work() Tetsuo Handa
2026-11-15 5:35 ` [PATCH v13 3/6] can: j1939: fix possibility of list corruption in __j1939_ecu_release() Tetsuo Handa
2026-11-15 5:35 ` [PATCH v13 4/6] can: j1939: add a safeguard to __j1939_ecu_release_work() Tetsuo Handa
2026-11-15 5:35 ` [PATCH v13 5/6] can: j1939: fix "struct j1939_ecu" refcount leak Tetsuo Handa
2026-11-15 5:36 ` [PATCH v13 6/6] can: j1939: fix possibility of hard-lockup/deadlock in j1939_ecu_timer_cancel() Tetsuo Handa
2026-11-15 5:51 ` 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=sashiko-outbox-215239@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox