]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: ethtool: Don't call .cleanup_data when prepare_data fails
authorMaxime Chevallier <maxime.chevallier@bootlin.com>
Mon, 7 Apr 2025 13:05:10 +0000 (15:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 05:43:52 +0000 (07:43 +0200)
[ Upstream commit 4f038a6a02d20859a3479293cbf172b0f14cbdd6 ]

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: c781ff12a2f3 ("ethtool: Allow network drivers to dump arbitrary EEPROM data")
Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20250407130511.75621-1-maxime.chevallier@bootlin.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/ethtool/netlink.c

index 0ffcd0e873b601b61fb094e1988bb2164bf522af..e35a3e5736cfdfc367ed8c0cce357c5956e0e7f7 100644 (file)
@@ -377,7 +377,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
        ret = ops->prepare_data(req_info, reply_data, info);
        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;
@@ -435,7 +435,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
        ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, NULL);
        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;
@@ -444,6 +444,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);
@@ -628,7 +629,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, NULL);
        if (ret < 0)
-               goto err_cleanup;
+               goto err_rep;
        ret = ops->reply_size(req_info, reply_data);
        if (ret < 0)
                goto err_cleanup;
@@ -664,6 +665,7 @@ err_skb:
 err_cleanup:
        if (ops->cleanup_data)
                ops->cleanup_data(reply_data);
+err_rep:
        kfree(reply_data);
        kfree(req_info);
        return;