* [PATCH can v1 0/2] can: j1939: resend lost patches for buffer init and netdevice tracking
@ 2026-07-28 5:58 Oleksij Rempel
2026-07-28 5:58 ` [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking Oleksij Rempel
2026-07-28 5:58 ` [PATCH v1 can 2/2] can: j1939: transport: initialize receive buffer Oleksij Rempel
0 siblings, 2 replies; 5+ messages in thread
From: Oleksij Rempel @ 2026-07-28 5:58 UTC (permalink / raw)
To: Robin van der Gracht, Oliver Hartkopp, Marc Kleine-Budde
Cc: Oleksij Rempel, kernel, linux-can, linux-kernel
This series collects and resends two j1939 patches that were previously
lost on their way upstream. They address different, unconnected issues
in the stack:
- Patch 1 prevents residual data leaks by zeroing the allocated receive
buffer in j1939_session_fresh_new().
- Patch 2 implements netdevice_tracker for j1939_{priv,session,ecu}
management to help investigate a dev_hold/dev_put refcount leak
(unregister_netdevice waiting for vcan0) reported by syzbot.
Oleksij Rempel (1):
can: j1939: transport: initialize receive buffer
Tetsuo Handa (1):
can: j1939: use netdevice_tracker for j1939_{priv,session,ecu}
tracking
net/can/j1939/bus.c | 2 ++
net/can/j1939/j1939-priv.h | 3 +++
net/can/j1939/main.c | 8 ++++----
net/can/j1939/transport.c | 4 +++-
4 files changed, 12 insertions(+), 5 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking
2026-07-28 5:58 [PATCH can v1 0/2] can: j1939: resend lost patches for buffer init and netdevice tracking Oleksij Rempel
@ 2026-07-28 5:58 ` Oleksij Rempel
2026-07-28 6:13 ` sashiko-bot
2026-07-28 5:58 ` [PATCH v1 can 2/2] can: j1939: transport: initialize receive buffer Oleksij Rempel
1 sibling, 1 reply; 5+ messages in thread
From: Oleksij Rempel @ 2026-07-28 5:58 UTC (permalink / raw)
To: Robin van der Gracht, Oliver Hartkopp, Marc Kleine-Budde
Cc: Tetsuo Handa, Oleksij Rempel, kernel, linux-can, linux-kernel
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
syzbot is still reporting
unregister_netdevice: waiting for vcan0 to become free. Usage count = 2
problem. A debug printk() patch in linux-next-20260508 identified that
there is dev_hold()/dev_put() imbalance in j1939_priv management.
Call trace for vcan0[26] +4 at
__dev_hold include/linux/netdevice.h:4470 [inline]
netdev_hold include/linux/netdevice.h:4513 [inline]
dev_hold include/linux/netdevice.h:4536 [inline]
j1939_priv_create net/can/j1939/main.c:140 [inline]
j1939_netdev_start+0x36b/0xc10 net/can/j1939/main.c:268
j1939_sk_bind+0x853/0xb30 net/can/j1939/socket.c:506
__sys_bind_socket net/socket.c:1948 [inline]
__sys_bind+0x2e9/0x410 net/socket.c:1979
Call trace for vcan0[28] -3 at
__dev_put include/linux/netdevice.h:4456 [inline]
netdev_put include/linux/netdevice.h:4523 [inline]
dev_put include/linux/netdevice.h:4548 [inline]
__j1939_priv_release net/can/j1939/main.c:166 [inline]
kref_put include/linux/kref.h:65 [inline]
j1939_priv_put+0x128/0x270 net/can/j1939/main.c:172
j1939_sk_sock_destruct+0x52/0x90 net/can/j1939/socket.c:388
__sk_destruct+0x8d/0x9d0 net/core/sock.c:2352
rcu_do_batch kernel/rcu/tree.c:2617 [inline]
rcu_core kernel/rcu/tree.c:2869 [inline]
rcu_cpu_kthread+0x99e/0x1470 kernel/rcu/tree.c:2957
smpboot_thread_fn+0x541/0xa50 kernel/smpboot.c:160
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
This refcount leak in j1939_priv might be caused by a refcount leak in
j1939_{session,ecu} because j1939_{session,ecu} holds a ref on j1939_priv.
For further investigation using upstream kernels, enable netdevice_tracker
in j1939_{priv,session,ecu} management.
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
net/can/j1939/bus.c | 2 ++
net/can/j1939/j1939-priv.h | 3 +++
net/can/j1939/main.c | 8 ++++----
net/can/j1939/transport.c | 2 ++
4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/net/can/j1939/bus.c b/net/can/j1939/bus.c
index dc374286eeb6..cdc3c0a71937 100644
--- a/net/can/j1939/bus.c
+++ b/net/can/j1939/bus.c
@@ -20,6 +20,7 @@ static void __j1939_ecu_release(struct kref *kref)
struct j1939_priv *priv = ecu->priv;
list_del(&ecu->list);
+ netdev_put(priv->ndev, &ecu->priv_dev_tracker);
kfree(ecu);
j1939_priv_put(priv);
}
@@ -155,6 +156,7 @@ struct j1939_ecu *j1939_ecu_create_locked(struct j1939_priv *priv, name_t name)
if (!ecu)
return ERR_PTR(-ENOMEM);
kref_init(&ecu->kref);
+ netdev_hold(priv->ndev, &ecu->priv_dev_tracker, gfp_any());
ecu->addr = J1939_IDLE_ADDR;
ecu->name = name;
diff --git a/net/can/j1939/j1939-priv.h b/net/can/j1939/j1939-priv.h
index 81f58924b4ac..cf26352d1d8c 100644
--- a/net/can/j1939/j1939-priv.h
+++ b/net/can/j1939/j1939-priv.h
@@ -38,6 +38,7 @@ struct j1939_ecu {
struct hrtimer ac_timer;
struct kref kref;
struct j1939_priv *priv;
+ netdevice_tracker priv_dev_tracker;
/* count users, to help transport protocol decide for interaction */
int nusers;
@@ -60,6 +61,7 @@ struct j1939_priv {
rwlock_t lock;
struct net_device *ndev;
+ netdevice_tracker dev_tracker;
/* list of 256 ecu ptrs, that cache the claimed addresses.
* also protected by the above lock
@@ -230,6 +232,7 @@ enum j1939_session_state {
struct j1939_session {
struct j1939_priv *priv;
+ netdevice_tracker priv_dev_tracker;
struct list_head active_session_list_entry;
struct list_head sk_session_queue_entry;
struct kref kref;
diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c
index 9937c04241bc..5e5e6c228f22 100644
--- a/net/can/j1939/main.c
+++ b/net/can/j1939/main.c
@@ -137,7 +137,7 @@ static struct j1939_priv *j1939_priv_create(struct net_device *ndev)
priv->ndev = ndev;
kref_init(&priv->kref);
kref_init(&priv->rx_kref);
- dev_hold(ndev);
+ netdev_hold(ndev, &priv->dev_tracker, GFP_KERNEL);
netdev_dbg(priv->ndev, "%s : 0x%p\n", __func__, priv);
@@ -163,7 +163,7 @@ static void __j1939_priv_release(struct kref *kref)
WARN_ON_ONCE(!list_empty(&priv->ecus));
WARN_ON_ONCE(!list_empty(&priv->j1939_socks));
- dev_put(ndev);
+ netdev_put(ndev, &priv->dev_tracker);
kfree(priv);
}
@@ -281,7 +281,7 @@ struct j1939_priv *j1939_netdev_start(struct net_device *ndev)
*/
kref_get(&priv_new->rx_kref);
mutex_unlock(&j1939_netdev_lock);
- dev_put(ndev);
+ netdev_put(ndev, &priv->dev_tracker);
kfree(priv);
return priv_new;
}
@@ -298,7 +298,7 @@ struct j1939_priv *j1939_netdev_start(struct net_device *ndev)
j1939_priv_set(ndev, NULL);
mutex_unlock(&j1939_netdev_lock);
- dev_put(ndev);
+ netdev_put(ndev, &priv->dev_tracker);
kfree(priv);
return ERR_PTR(ret);
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 8a31cb23bc76..98f96362b20f 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -283,6 +283,7 @@ static void j1939_session_destroy(struct j1939_session *session)
kfree_skb(skb);
}
__j1939_session_drop(session);
+ netdev_put(session->priv->ndev, &session->priv_dev_tracker);
j1939_priv_put(session->priv);
kfree(session);
}
@@ -1526,6 +1527,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv,
INIT_LIST_HEAD(&session->active_session_list_entry);
INIT_LIST_HEAD(&session->sk_session_queue_entry);
kref_init(&session->kref);
+ netdev_hold(priv->ndev, &session->priv_dev_tracker, gfp_any());
j1939_priv_get(priv);
session->priv = priv;
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v1 can 2/2] can: j1939: transport: initialize receive buffer
2026-07-28 5:58 [PATCH can v1 0/2] can: j1939: resend lost patches for buffer init and netdevice tracking Oleksij Rempel
2026-07-28 5:58 ` [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking Oleksij Rempel
@ 2026-07-28 5:58 ` Oleksij Rempel
1 sibling, 0 replies; 5+ messages in thread
From: Oleksij Rempel @ 2026-07-28 5:58 UTC (permalink / raw)
To: Robin van der Gracht, Oliver Hartkopp, Marc Kleine-Budde
Cc: Oleksij Rempel, Ji'an Zhou, kernel, linux-can, linux-kernel
Zero the allocated buffer in j1939_session_fresh_new() to ensure it
contains no residual data.
While there is a potential performance impact if users allocate maximum
sized ETP buffers, most real-world use cases are not noticeably affected
since the maximum known buffer size is typically around 65K.
Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
Reported-by: Ji'an Zhou <eilaimemedsnaimel@gmail.com>
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
net/can/j1939/transport.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
index 98f96362b20f..8fcfd13e5e6f 100644
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -1581,7 +1581,7 @@ j1939_session *j1939_session_fresh_new(struct j1939_priv *priv,
}
/* alloc data area */
- skb_put(skb, size);
+ skb_put_zero(skb, size);
/* skb is recounted in j1939_session_new() */
return session;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking
2026-07-28 5:58 ` [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking Oleksij Rempel
@ 2026-07-28 6:13 ` sashiko-bot
2026-07-28 13:06 ` Oleksij Rempel
0 siblings, 1 reply; 5+ messages in thread
From: sashiko-bot @ 2026-07-28 6:13 UTC (permalink / raw)
To: Oleksij Rempel
Cc: Vincent Mailhol, Oleksij Rempel, Oliver Hartkopp, linux-can,
Marc Kleine-Budde
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] ECU list `priv->ecus` is modified locklessly during concurrent unmapping.
--
--- Patch [1]: [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking ---
commit fa6ae711cbc8e468a294fc1a54de5efa19c0b5b3
Author: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking
This patch enables netdevice_tracker for j1939_priv, j1939_session, and
j1939_ecu structures. It aims to help identify the source of refcount
leaks reported by syzbot during unregister_netdevice().
> diff --git a/net/can/j1939/bus.c b/net/can/j1939/bus.c
> index dc374286eeb6e..cdc3c0a719379 100644
> --- a/net/can/j1939/bus.c
> +++ b/net/can/j1939/bus.c
> @@ -20,6 +20,7 @@ static void __j1939_ecu_release(struct kref *kref)
> struct j1939_priv *priv = ecu->priv;
>
> list_del(&ecu->list);
[Severity: High]
This is a pre-existing issue, but is it safe to modify priv->ecus here without
holding priv->lock?
If a process unbinds a socket and drops its ECU reference concurrently with the
network receive path processing a packet:
CPU1 (Socket thread)
j1939_local_ecu_put()
/* drops refcount to 1 */
CPU2 (SoftIRQ)
j1939_ac_recv()
j1939_ecu_put(ecu); /* locklessly drops final reference */
This leads to __j1939_ecu_release() executing list_del(&ecu->list) and
kfree(ecu) without holding priv->lock.
Can this happen concurrently with other threads iterating priv->ecus under
priv->lock, potentially resulting in data races, list corruption, and
use-after-free bugs?
> + netdev_put(priv->ndev, &ecu->priv_dev_tracker);
> kfree(ecu);
> j1939_priv_put(priv);
> }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260728055835.1151785-1-o.rempel@pengutronix.de?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking
2026-07-28 6:13 ` sashiko-bot
@ 2026-07-28 13:06 ` Oleksij Rempel
0 siblings, 0 replies; 5+ messages in thread
From: Oleksij Rempel @ 2026-07-28 13:06 UTC (permalink / raw)
To: sashiko-reviews
Cc: Vincent Mailhol, Oliver Hartkopp, linux-can, Marc Kleine-Budde
On Tue, Jul 28, 2026 at 06:13:38AM +0000, sashiko-bot@kernel.org wrote:
> --- Patch [1]: [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking ---
> commit fa6ae711cbc8e468a294fc1a54de5efa19c0b5b3
> Author: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
>
> can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking
>
> This patch enables netdevice_tracker for j1939_priv, j1939_session, and
> j1939_ecu structures. It aims to help identify the source of refcount
> leaks reported by syzbot during unregister_netdevice().
>
> > diff --git a/net/can/j1939/bus.c b/net/can/j1939/bus.c
> > index dc374286eeb6e..cdc3c0a719379 100644
> > --- a/net/can/j1939/bus.c
> > +++ b/net/can/j1939/bus.c
> > @@ -20,6 +20,7 @@ static void __j1939_ecu_release(struct kref *kref)
> > struct j1939_priv *priv = ecu->priv;
> >
> > list_del(&ecu->list);
>
> [Severity: High]
> This is a pre-existing issue, but is it safe to modify priv->ecus here without
> holding priv->lock?
>
> If a process unbinds a socket and drops its ECU reference concurrently with the
> network receive path processing a packet:
Ack - we will keep it mind. This is not blocker for current patch set.
Best Regards,
Oleksij
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-28 13:06 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-28 5:58 [PATCH can v1 0/2] can: j1939: resend lost patches for buffer init and netdevice tracking Oleksij Rempel
2026-07-28 5:58 ` [PATCH can v1 1/2] can: j1939: use netdevice_tracker for j1939_{priv,session,ecu} tracking Oleksij Rempel
2026-07-28 6:13 ` sashiko-bot
2026-07-28 13:06 ` Oleksij Rempel
2026-07-28 5:58 ` [PATCH v1 can 2/2] can: j1939: transport: initialize receive buffer Oleksij Rempel
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.