Commit 8750939b6ad86abc3f53ec8a9683a1cded4a5654

Authored by Jakub Kicinski
Committed by David S. Miller
1 parent ab124d580a

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: e3b7ca18ad7b ("devlink: Add param set command")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 19 additions and 12 deletions Side-by-side Diff

... ... @@ -3352,34 +3352,41 @@
3352 3352 struct genl_info *info,
3353 3353 union devlink_param_value *value)
3354 3354 {
  3355 + struct nlattr *param_data;
3355 3356 int len;
3356 3357  
3357   - if (param->type != DEVLINK_PARAM_TYPE_BOOL &&
3358   - !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])
  3358 + param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
  3359 +
  3360 + if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
3359 3361 return -EINVAL;
3360 3362  
3361 3363 switch (param->type) {
3362 3364 case DEVLINK_PARAM_TYPE_U8:
3363   - value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
  3365 + if (nla_len(param_data) != sizeof(u8))
  3366 + return -EINVAL;
  3367 + value->vu8 = nla_get_u8(param_data);
3364 3368 break;
3365 3369 case DEVLINK_PARAM_TYPE_U16:
3366   - value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
  3370 + if (nla_len(param_data) != sizeof(u16))
  3371 + return -EINVAL;
  3372 + value->vu16 = nla_get_u16(param_data);
3367 3373 break;
3368 3374 case DEVLINK_PARAM_TYPE_U32:
3369   - value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
  3375 + if (nla_len(param_data) != sizeof(u32))
  3376 + return -EINVAL;
  3377 + value->vu32 = nla_get_u32(param_data);
3370 3378 break;
3371 3379 case DEVLINK_PARAM_TYPE_STRING:
3372   - len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]),
3373   - nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3374   - if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ||
  3380 + len = strnlen(nla_data(param_data), nla_len(param_data));
  3381 + if (len == nla_len(param_data) ||
3375 3382 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3376 3383 return -EINVAL;
3377   - strcpy(value->vstr,
3378   - nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
  3384 + strcpy(value->vstr, nla_data(param_data));
3379 3385 break;
3380 3386 case DEVLINK_PARAM_TYPE_BOOL:
3381   - value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
3382   - true : false;
  3387 + if (param_data && nla_len(param_data))
  3388 + return -EINVAL;
  3389 + value->vbool = nla_get_flag(param_data);
3383 3390 break;
3384 3391 }
3385 3392 return 0;