mirror of
https://github.com/torvalds/linux.git
synced 2026-09-14 16:10:02 +02:00
Merge patch series "can: j1939: resend lost patches for buffer init and netdevice tracking"
Oleksij Rempel <o.rempel@pengutronix.de> says:
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.
Link: https://patch.msgid.link/20260728055835.1151785-1-o.rempel@pengutronix.de
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
This commit is contained in:
commit
c08413d10b
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -1579,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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user