Commit 8750939b authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

devlink: validate length of param values

DEVLINK_ATTR_PARAM_VALUE_DATA may have different types
so it's not checked by the normal netlink policy. Make
sure the attribute length is what we expect.

Fixes: e3b7ca18 ("devlink: Add param set command")
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Reviewed-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ab124d58
...@@ -3352,34 +3352,41 @@ devlink_param_value_get_from_info(const struct devlink_param *param, ...@@ -3352,34 +3352,41 @@ devlink_param_value_get_from_info(const struct devlink_param *param,
struct genl_info *info, struct genl_info *info,
union devlink_param_value *value) union devlink_param_value *value)
{ {
struct nlattr *param_data;
int len; int len;
if (param->type != DEVLINK_PARAM_TYPE_BOOL && param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
!info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])
if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
return -EINVAL; return -EINVAL;
switch (param->type) { switch (param->type) {
case DEVLINK_PARAM_TYPE_U8: case DEVLINK_PARAM_TYPE_U8:
value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); if (nla_len(param_data) != sizeof(u8))
return -EINVAL;
value->vu8 = nla_get_u8(param_data);
break; break;
case DEVLINK_PARAM_TYPE_U16: case DEVLINK_PARAM_TYPE_U16:
value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); if (nla_len(param_data) != sizeof(u16))
return -EINVAL;
value->vu16 = nla_get_u16(param_data);
break; break;
case DEVLINK_PARAM_TYPE_U32: case DEVLINK_PARAM_TYPE_U32:
value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); if (nla_len(param_data) != sizeof(u32))
return -EINVAL;
value->vu32 = nla_get_u32(param_data);
break; break;
case DEVLINK_PARAM_TYPE_STRING: case DEVLINK_PARAM_TYPE_STRING:
len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]), len = strnlen(nla_data(param_data), nla_len(param_data));
nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])); if (len == nla_len(param_data) ||
if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ||
len >= __DEVLINK_PARAM_MAX_STRING_VALUE) len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
return -EINVAL; return -EINVAL;
strcpy(value->vstr, strcpy(value->vstr, nla_data(param_data));
nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
break; break;
case DEVLINK_PARAM_TYPE_BOOL: case DEVLINK_PARAM_TYPE_BOOL:
value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ? if (param_data && nla_len(param_data))
true : false; return -EINVAL;
value->vbool = nla_get_flag(param_data);
break; break;
} }
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment