Commit 8750939b6ad86abc3f53ec8a9683a1cded4a5654
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
net/core/devlink.c
... | ... | @@ -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; |