mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
ethtool: module: fix cleanup if socket used for flashing multiple devices
When a single Netlink socket issues MODULE_FW_FLASH_ACT against multiple
devices, ethnl_sock_priv_set() overwrites sk_priv->dev on each call,
retaining only the last one. The socket priv is used on socket close,
to walk the global work list and mark the uncompleted flashing work
as "orphaned". Otherwise if another socket reuses the PID it will
unexpectedly receive the flashing notifications.
Don't record the device, record net pointer instead. The purpose of
the dev is to scope the work to a netns, anyway. If we store netns
the overrides are safe/a nop since all flashed devices must be in
the same netns as the socket.
Fixes: 32b4c8b53e ("ethtool: Add ability to flash transceiver modules' firmware")
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Link: https://patch.msgid.link/20260522231312.1710836-6-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
504eaefa44
commit
760d04ebad
|
|
@ -291,11 +291,9 @@ void ethnl_module_fw_flash_sock_destroy(struct ethnl_sock_priv *sk_priv)
|
|||
|
||||
spin_lock(&module_fw_flash_work_list_lock);
|
||||
list_for_each_entry(work, &module_fw_flash_work_list, list) {
|
||||
if (work->fw_update.dev == sk_priv->dev &&
|
||||
work->fw_update.ntf_params.portid == sk_priv->portid) {
|
||||
if (work->fw_update.ntf_params.portid == sk_priv->portid &&
|
||||
dev_net(work->fw_update.dev) == sk_priv->net)
|
||||
work->fw_update.ntf_params.closed_sock = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
spin_unlock(&module_fw_flash_work_list_lock);
|
||||
}
|
||||
|
|
@ -332,7 +330,8 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name,
|
|||
fw_update->ntf_params.seq = info->snd_seq;
|
||||
fw_update->ntf_params.closed_sock = false;
|
||||
|
||||
err = ethnl_sock_priv_set(skb, dev, fw_update->ntf_params.portid,
|
||||
err = ethnl_sock_priv_set(skb, dev_net(dev),
|
||||
fw_update->ntf_params.portid,
|
||||
ETHTOOL_SOCK_TYPE_MODULE_FW_FLASH);
|
||||
if (err < 0)
|
||||
goto err_release_firmware;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const struct nla_policy ethnl_header_policy_phy_stats[] = {
|
|||
[ETHTOOL_A_HEADER_PHY_INDEX] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
};
|
||||
|
||||
int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
|
||||
int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
|
||||
enum ethnl_sock_type type)
|
||||
{
|
||||
struct ethnl_sock_priv *sk_priv;
|
||||
|
|
@ -62,7 +62,7 @@ int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
|
|||
if (IS_ERR(sk_priv))
|
||||
return PTR_ERR(sk_priv);
|
||||
|
||||
sk_priv->dev = dev;
|
||||
sk_priv->net = net;
|
||||
sk_priv->portid = portid;
|
||||
sk_priv->type = type;
|
||||
|
||||
|
|
|
|||
|
|
@ -318,12 +318,12 @@ enum ethnl_sock_type {
|
|||
};
|
||||
|
||||
struct ethnl_sock_priv {
|
||||
struct net_device *dev;
|
||||
struct net *net;
|
||||
u32 portid;
|
||||
enum ethnl_sock_type type;
|
||||
};
|
||||
|
||||
int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
|
||||
int ethnl_sock_priv_set(struct sk_buff *skb, struct net *net, u32 portid,
|
||||
enum ethnl_sock_type type);
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user