Commit 4f038a6a authored by Maxime Chevallier's avatar Maxime Chevallier Committed by Paolo Abeni
Browse files

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 successful .prepare_data() as per the documentation.

Rewrite the error-handling paths to make sure we don't cleanup
un-prepared data.

Fixes: c781ff12 ("ethtool: Allow network drivers to dump arbitrary EEPROM data")
Reviewed-by: default avatarKory Maincent <kory.maincent@bootlin.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Reviewed-by: default avatarMichal Kubecek <mkubecek@suse.cz>
Signed-off-by: default avatarMaxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20250407130511.75621-1-maxime.chevallier@bootlin.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 369609fc
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -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;