summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorLudvig Pärsson <ludvig.parsson@axis.com>2024-01-17 13:03:14 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-01-25 14:37:56 -0800
commitf90b1cebc442b83ffb6460cd12923a9ee3331522 (patch)
tree27e35a4b898516f8d55e61f79134dde3aa8e02ee /net
parentb44e1aec8038d9007e988f7068f333fa0ad73943 (diff)
downloadlinux-f90b1cebc442b83ffb6460cd12923a9ee3331522.tar.gz
linux-f90b1cebc442b83ffb6460cd12923a9ee3331522.tar.bz2
linux-f90b1cebc442b83ffb6460cd12923a9ee3331522.zip
ethtool: netlink: Add missing ethnl_ops_begin/complete
[ Upstream commit f1172f3ee3a98754d95b968968920a7d03fdebcc ] Accessing an ethernet device that is powered off or clock gated might cause the CPU to hang. Add ethnl_ops_begin/complete in ethnl_set_features() to protect against this. Fixes: 0980bfcd6954 ("ethtool: set netdev features with FEATURES_SET request") Signed-off-by: Ludvig Pärsson <ludvig.parsson@axis.com> Link: https://lore.kernel.org/r/20240117-etht2-v2-1-1a96b6e8c650@axis.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/ethtool/features.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/ethtool/features.c b/net/ethtool/features.c
index 1c9f4df273bd..faccab84d865 100644
--- a/net/ethtool/features.c
+++ b/net/ethtool/features.c
@@ -235,17 +235,20 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
dev = req_info.dev;
rtnl_lock();
+ ret = ethnl_ops_begin(dev);
+ if (ret < 0)
+ goto out_rtnl;
ethnl_features_to_bitmap(old_active, dev->features);
ethnl_features_to_bitmap(old_wanted, dev->wanted_features);
ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
tb[ETHTOOL_A_FEATURES_WANTED],
netdev_features_strings, info->extack);
if (ret < 0)
- goto out_rtnl;
+ goto out_ops;
if (ethnl_bitmap_to_features(req_mask) & ~NETIF_F_ETHTOOL_BITS) {
GENL_SET_ERR_MSG(info, "attempt to change non-ethtool features");
ret = -EINVAL;
- goto out_rtnl;
+ goto out_ops;
}
/* set req_wanted bits not in req_mask from old_wanted */
@@ -282,6 +285,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
if (mod)
netdev_features_change(dev);
+out_ops:
+ ethnl_ops_complete(dev);
out_rtnl:
rtnl_unlock();
dev_put(dev);