forked from mirrors/linux
eth: fbnic: Update fbnic_tlv_attr_get_string() to work like nla_strscpy()
Allow fbnic_tlv_attr_get_string() to return an error code. In the event the source mailbox attribute is missing return -EINVAL. Like nla_strscpy() return -E2BIG when the source string is larger than the destination string. In this case the amount of data copied is equal to dstsize. Signed-off-by: Lee Trager <lee@trager.us> Link: https://patch.msgid.link/20250228191935.3953712-3-lee@trager.us Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
56bcc6ecff
commit
e5cf5107c9
2 changed files with 32 additions and 11 deletions
|
|
@ -233,19 +233,40 @@ s64 fbnic_tlv_attr_get_signed(struct fbnic_tlv_msg *attr)
|
|||
/**
|
||||
* fbnic_tlv_attr_get_string - Retrieve string value from result
|
||||
* @attr: Attribute to retrieve data from
|
||||
* @str: Pointer to an allocated string to store the data
|
||||
* @max_size: The maximum size which can be in str
|
||||
* @dst: Pointer to an allocated string to store the data
|
||||
* @dstsize: The maximum size which can be in dst
|
||||
*
|
||||
* Return: the size of the string read from firmware
|
||||
* Return: the size of the string read from firmware or negative error.
|
||||
**/
|
||||
size_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *str,
|
||||
size_t max_size)
|
||||
ssize_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *dst,
|
||||
size_t dstsize)
|
||||
{
|
||||
max_size = min_t(size_t, max_size,
|
||||
(le16_to_cpu(attr->hdr.len) * 4) - sizeof(*attr));
|
||||
memcpy(str, &attr->value, max_size);
|
||||
size_t srclen, len;
|
||||
ssize_t ret;
|
||||
|
||||
return max_size;
|
||||
if (!attr)
|
||||
return -EINVAL;
|
||||
|
||||
if (dstsize == 0)
|
||||
return -E2BIG;
|
||||
|
||||
srclen = le16_to_cpu(attr->hdr.len) - sizeof(*attr);
|
||||
if (srclen > 0 && attr->value[srclen - 1] == '\0')
|
||||
srclen--;
|
||||
|
||||
if (srclen >= dstsize) {
|
||||
len = dstsize - 1;
|
||||
ret = -E2BIG;
|
||||
} else {
|
||||
len = srclen;
|
||||
ret = len;
|
||||
}
|
||||
|
||||
memcpy(dst, &attr->value, len);
|
||||
/* Zero pad end of dst. */
|
||||
memset(dst + len, 0, dstsize - len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@ static inline bool fbnic_tlv_attr_get_bool(struct fbnic_tlv_msg *attr)
|
|||
|
||||
u64 fbnic_tlv_attr_get_unsigned(struct fbnic_tlv_msg *attr);
|
||||
s64 fbnic_tlv_attr_get_signed(struct fbnic_tlv_msg *attr);
|
||||
size_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *str,
|
||||
size_t max_size);
|
||||
ssize_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *dst,
|
||||
size_t dstsize);
|
||||
|
||||
#define get_unsigned_result(id, location) \
|
||||
do { \
|
||||
|
|
|
|||
Loading…
Reference in a new issue