Linux CAN drivers development
 help / color / mirror / Atom feed
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

  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