Commit f946270d authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

ethtool: netlink: always pass genl_info to .prepare_data



We had a number of bugs in the past because developers forgot
to fully test dumps, which pass NULL as info to .prepare_data.
.prepare_data implementations would try to access info->extack
leading to a null-deref.

Now that dumps and notifications can access struct genl_info
we can pass it in, and remove the info null checks.

Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> # pause
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20230814214723.2924989-11-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ec0e5b09
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ const struct nla_policy ethnl_channels_get_policy[] = {

static int channels_prepare_data(const struct ethnl_req_info *req_base,
				 struct ethnl_reply_data *reply_base,
				 struct genl_info *info)
				 const struct genl_info *info)
{
	struct channels_reply_data *data = CHANNELS_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
+3 −3
Original line number Diff line number Diff line
@@ -59,10 +59,9 @@ const struct nla_policy ethnl_coalesce_get_policy[] = {

static int coalesce_prepare_data(const struct ethnl_req_info *req_base,
				 struct ethnl_reply_data *reply_base,
				 struct genl_info *info)
				 const struct genl_info *info)
{
	struct coalesce_reply_data *data = COALESCE_REPDATA(reply_base);
	struct netlink_ext_ack *extack = info ? info->extack : NULL;
	struct net_device *dev = reply_base->dev;
	int ret;

@@ -73,7 +72,8 @@ static int coalesce_prepare_data(const struct ethnl_req_info *req_base,
	if (ret < 0)
		return ret;
	ret = dev->ethtool_ops->get_coalesce(dev, &data->coalesce,
					     &data->kernel_coalesce, extack);
					     &data->kernel_coalesce,
					     info->extack);
	ethnl_ops_complete(dev);

	return ret;
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ const struct nla_policy ethnl_debug_get_policy[] = {

static int debug_prepare_data(const struct ethnl_req_info *req_base,
			      struct ethnl_reply_data *reply_base,
			      struct genl_info *info)
			      const struct genl_info *info)
{
	struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ const struct nla_policy ethnl_eee_get_policy[] = {

static int eee_prepare_data(const struct ethnl_req_info *req_base,
			    struct ethnl_reply_data *reply_base,
			    struct genl_info *info)
			    const struct genl_info *info)
{
	struct eee_reply_data *data = EEE_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
+4 −5
Original line number Diff line number Diff line
@@ -51,8 +51,7 @@ static int fallback_set_params(struct eeprom_req_info *request,
}

static int eeprom_fallback(struct eeprom_req_info *request,
			   struct eeprom_reply_data *reply,
			   struct genl_info *info)
			   struct eeprom_reply_data *reply)
{
	struct net_device *dev = reply->base.dev;
	struct ethtool_modinfo modinfo = {0};
@@ -103,7 +102,7 @@ static int get_module_eeprom_by_page(struct net_device *dev,

static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
			       struct ethnl_reply_data *reply_base,
			       struct genl_info *info)
			       const struct genl_info *info)
{
	struct eeprom_reply_data *reply = MODULE_EEPROM_REPDATA(reply_base);
	struct eeprom_req_info *request = MODULE_EEPROM_REQINFO(req_base);
@@ -124,7 +123,7 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
	if (ret)
		goto err_free;

	ret = get_module_eeprom_by_page(dev, &page_data, info ? info->extack : NULL);
	ret = get_module_eeprom_by_page(dev, &page_data, info->extack);
	if (ret < 0)
		goto err_ops;

@@ -140,7 +139,7 @@ static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
	kfree(page_data.data);

	if (ret == -EOPNOTSUPP)
		return eeprom_fallback(request, reply, info);
		return eeprom_fallback(request, reply);
	return ret;
}

Loading