diff options
Diffstat (limited to 'net/core/devlink.c')
| -rw-r--r-- | net/core/devlink.c | 43 | 
1 files changed, 37 insertions, 6 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c index 6dae81d65d5c..3a4b29a13d31 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3012,6 +3012,8 @@ devlink_param_value_get_from_info(const struct devlink_param *param,  				  struct genl_info *info,  				  union devlink_param_value *value)  { +	int len; +  	if (param->type != DEVLINK_PARAM_TYPE_BOOL &&  	    !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])  		return -EINVAL; @@ -3027,10 +3029,13 @@ devlink_param_value_get_from_info(const struct devlink_param *param,  		value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);  		break;  	case DEVLINK_PARAM_TYPE_STRING: -		if (nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) > -		    DEVLINK_PARAM_MAX_STRING_VALUE) +		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)  			return -EINVAL; -		value->vstr = nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]); +		strcpy(value->vstr, +		       nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));  		break;  	case DEVLINK_PARAM_TYPE_BOOL:  		value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ? @@ -3117,7 +3122,10 @@ static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,  		return -EOPNOTSUPP;  	if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) { -		param_item->driverinit_value = value; +		if (param->type == DEVLINK_PARAM_TYPE_STRING) +			strcpy(param_item->driverinit_value.vstr, value.vstr); +		else +			param_item->driverinit_value = value;  		param_item->driverinit_value_valid = true;  	} else {  		if (!param->set) @@ -4557,7 +4565,10 @@ int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,  					      DEVLINK_PARAM_CMODE_DRIVERINIT))  		return -EOPNOTSUPP; -	*init_val = param_item->driverinit_value; +	if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) +		strcpy(init_val->vstr, param_item->driverinit_value.vstr); +	else +		*init_val = param_item->driverinit_value;  	return 0;  } @@ -4588,7 +4599,10 @@ int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,  					      DEVLINK_PARAM_CMODE_DRIVERINIT))  		return -EOPNOTSUPP; -	param_item->driverinit_value = init_val; +	if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING) +		strcpy(param_item->driverinit_value.vstr, init_val.vstr); +	else +		param_item->driverinit_value = init_val;  	param_item->driverinit_value_valid = true;  	devlink_param_notify(devlink, param_item, DEVLINK_CMD_PARAM_NEW); @@ -4621,6 +4635,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   *   *	@devlink: devlink  | 
