Linux CAN drivers development
 help / color / mirror / Atom feed
* [PATCH] can: j1939: close theoretical race window in j1939_sk_netdev_event_unregister()
@ 2025-09-24 14:16 Tetsuo Handa
  2025-11-25 13:43 ` [PATCH v2] can: j1939: make j1939_sk_bind() fail if device is no longer registered Tetsuo Handa
  0 siblings, 1 reply; 4+ messages in thread
From: Tetsuo Handa @ 2025-09-24 14:16 UTC (permalink / raw)
  To: Robin van der Gracht, Oleksij Rempel, kernel, Oliver Hartkopp,
	Marc Kleine-Budde, linux-can

There is a theoretical race window in j1939_sk_netdev_event_unregister()
where two j1939_sk_bind() calls jump in between read_unlock_bh() and
lock_sock().

The assumption jsk->priv == priv can fail if the first j1939_sk_bind()
call once made jsk->priv == NULL due to failed j1939_local_ecu_get() call
and the second call again made jsk->priv != NULL due to successful
j1939_local_ecu_get() call.

Close this race by also checking jsk->priv == priv.

Fixes: 7fcbe5b2c6a4 ("can: j1939: implement NETDEV_UNREGISTER notification handler")
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
Do we want to make j1939_sk_bind() transactional (i.e. don't make any changes
when it fails) after j1939_sk_bind() once succeeded, for the J1939_SOCK_BOUND
state being cleared might be an unexpected behavior?
Or, programs will just close() or exit() if re-bind() request failed?

 net/can/j1939/socket.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index 88e7160d4248..0a377ad75038 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -1313,7 +1313,7 @@ void j1939_sk_netdev_event_unregister(struct j1939_priv *priv)
 	read_lock_bh(&priv->j1939_socks_lock);
 	list_for_each_entry(jsk, &priv->j1939_socks, list) {
 		/* Skip if j1939_jsk_add() is not called on this socket. */
-		if (!(jsk->state & J1939_SOCK_BOUND))
+		if (!(jsk->state & J1939_SOCK_BOUND) || jsk->priv != priv)
 			continue;
 		sk = &jsk->sk;
 		sock_hold(sk);
@@ -1323,7 +1323,7 @@ void j1939_sk_netdev_event_unregister(struct j1939_priv *priv)
 		 * j1939_jsk_del() with socket's lock held.
 		 */
 		lock_sock(sk);
-		if (jsk->state & J1939_SOCK_BOUND) {
+		if ((jsk->state & J1939_SOCK_BOUND) && jsk->priv == priv) {
 			/* Neither j1939_sk_bind() nor j1939_sk_release() called j1939_jsk_del().
 			 * Make this socket no longer bound, by pretending as if j1939_sk_bind()
 			 * dropped old references but did not get new references.
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-12-17  9:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-24 14:16 [PATCH] can: j1939: close theoretical race window in j1939_sk_netdev_event_unregister() Tetsuo Handa
2025-11-25 13:43 ` [PATCH v2] can: j1939: make j1939_sk_bind() fail if device is no longer registered Tetsuo Handa
2025-12-11  9:49   ` Oleksij Rempel
2025-12-17  9:48   ` Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox