[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250403132448.405266-1-maxime.chevallier@bootlin.com>
Date: Thu, 3 Apr 2025 15:24:46 +0200
From: Maxime Chevallier <maxime.chevallier@...tlin.com>
To: davem@...emloft.net,
Andrew Lunn <andrew@...n.ch>,
Jakub Kicinski <kuba@...nel.org>,
Eric Dumazet <edumazet@...gle.com>,
Paolo Abeni <pabeni@...hat.com>
Cc: Maxime Chevallier <maxime.chevallier@...tlin.com>,
netdev@...r.kernel.org,
linux-kernel@...r.kernel.org,
thomas.petazzoni@...tlin.com,
Simon Horman <horms@...nel.org>,
Michal Kubecek <mkubecek@...e.cz>,
Florian Fainelli <f.fainelli@...il.com>,
Kory Maincent <kory.maincent@...tlin.com>
Subject: [PATCH net] net: ethtool: Don't call .cleanup_data when prepare_data fails
There's a consistent pattern where the .cleanup_data() callback is
called when .prepare_data() fails, when it should really be called to
clean after a successfull .prepare_data() as per the documentation.
Rewrite the error-handling paths to make sure we don't cleanup
un-prepared data.
Fixes: 728480f12442 ("ethtool: default handlers for GET requests")
Reviewed-by: Kory Maincent <kory.maincent@...tlin.com>
Signed-off-by: Maxime Chevallier <maxime.chevallier@...tlin.com>
---
net/ethtool/netlink.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index a163d40c6431..977beeaaa2f9 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -500,7 +500,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
netdev_unlock_ops(req_info->dev);
rtnl_unlock();
if (ret < 0)
- goto err_cleanup;
+ goto err_dev;
ret = ops->reply_size(req_info, reply_data);
if (ret < 0)
goto err_cleanup;
@@ -560,7 +560,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
netdev_unlock_ops(dev);
rtnl_unlock();
if (ret < 0)
- goto out;
+ goto out_cancel;
ret = ethnl_fill_reply_header(skb, dev, ctx->ops->hdr_attr);
if (ret < 0)
goto out;
@@ -569,6 +569,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
out:
if (ctx->ops->cleanup_data)
ctx->ops->cleanup_data(ctx->reply_data);
+out_cancel:
ctx->reply_data->dev = NULL;
if (ret < 0)
genlmsg_cancel(skb, ehdr);
@@ -793,7 +794,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
ethnl_init_reply_data(reply_data, ops, dev);
ret = ops->prepare_data(req_info, reply_data, &info);
if (ret < 0)
- goto err_cleanup;
+ goto err_rep;
ret = ops->reply_size(req_info, reply_data);
if (ret < 0)
goto err_cleanup;
@@ -828,6 +829,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
err_cleanup:
if (ops->cleanup_data)
ops->cleanup_data(reply_data);
+err_rep:
kfree(reply_data);
kfree(req_info);
return;
--
2.49.0
Powered by blists - more mailing lists