From f355cfcdb251e22b9dfb78c0eef4005a9d902a35 Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Wed, 10 Oct 2018 16:09:25 +0300 Subject: devlink: Fix param set handling for string type In case devlink param type is string, it needs to copy the string value it got from the input to devlink_param_value. Fixes: e3b7ca18ad7b ("devlink: Add param set command") Signed-off-by: Moshe Shemesh Signed-off-by: David S. Miller --- include/net/devlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/net/devlink.h') diff --git a/include/net/devlink.h b/include/net/devlink.h index b9b89d6604d4..b0e17c025fdc 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -311,7 +311,7 @@ union devlink_param_value { u8 vu8; u16 vu16; u32 vu32; - const char *vstr; + char vstr[DEVLINK_PARAM_MAX_STRING_VALUE]; bool vbool; }; -- cgit v1.2.3 From bde74ad10eb55aaa472c37b107934e6b8563c25e Mon Sep 17 00:00:00 2001 From: Moshe Shemesh Date: Wed, 10 Oct 2018 16:09:27 +0300 Subject: devlink: Add helper function for safely copy string param Devlink string param buffer is allocated at the size of DEVLINK_PARAM_MAX_STRING_VALUE. Add helper function which makes sure this size is not exceeded. Renamed DEVLINK_PARAM_MAX_STRING_VALUE to __DEVLINK_PARAM_MAX_STRING_VALUE to emphasize that it should be used by devlink only. The driver should use the helper function instead to verify it doesn't exceed the allowed length. Signed-off-by: Moshe Shemesh Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- include/net/devlink.h | 12 ++++++++++-- net/core/devlink.c | 19 ++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) (limited to 'include/net/devlink.h') diff --git a/include/net/devlink.h b/include/net/devlink.h index b0e17c025fdc..99efc156a309 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -298,7 +298,7 @@ struct devlink_resource { #define DEVLINK_RESOURCE_ID_PARENT_TOP 0 -#define DEVLINK_PARAM_MAX_STRING_VALUE 32 +#define __DEVLINK_PARAM_MAX_STRING_VALUE 32 enum devlink_param_type { DEVLINK_PARAM_TYPE_U8, DEVLINK_PARAM_TYPE_U16, @@ -311,7 +311,7 @@ union devlink_param_value { u8 vu8; u16 vu16; u32 vu32; - char vstr[DEVLINK_PARAM_MAX_STRING_VALUE]; + char vstr[__DEVLINK_PARAM_MAX_STRING_VALUE]; bool vbool; }; @@ -553,6 +553,8 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id, union devlink_param_value init_val); void devlink_param_value_changed(struct devlink *devlink, u32 param_id); +void devlink_param_value_str_fill(union devlink_param_value *dst_val, + const char *src); struct devlink_region *devlink_region_create(struct devlink *devlink, const char *region_name, u32 region_max_snapshots, @@ -789,6 +791,12 @@ devlink_param_value_changed(struct devlink *devlink, u32 param_id) { } +static inline void +devlink_param_value_str_fill(union devlink_param_value *dst_val, + const char *src) +{ +} + static inline struct devlink_region * devlink_region_create(struct devlink *devlink, const char *region_name, diff --git a/net/core/devlink.c b/net/core/devlink.c index 1a0de1677197..6bc42933be4a 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3015,7 +3015,7 @@ devlink_param_value_get_from_info(const struct devlink_param *param, len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]), nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_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; strcpy(value->vstr, nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])); @@ -4617,6 +4617,23 @@ void devlink_param_value_changed(struct devlink *devlink, u32 param_id) } EXPORT_SYMBOL_GPL(devlink_param_value_changed); +/** + * devlink_param_value_str_fill - Safely fill-up the string preventing + * from overflow of the preallocated buffer + * + * @dst_val: destination devlink_param_value + * @src: source buffer + */ +void devlink_param_value_str_fill(union devlink_param_value *dst_val, + const char *src) +{ + size_t len; + + len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE); + WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE); +} +EXPORT_SYMBOL_GPL(devlink_param_value_str_fill); + /** * devlink_region_create - create a new address region * -- cgit v1.2.3