3
0
Fork 0
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:
Lee Trager 2025-02-28 11:15:27 -08:00 committed by Jakub Kicinski
parent 56bcc6ecff
commit e5cf5107c9
2 changed files with 32 additions and 11 deletions

View file

@ -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 * fbnic_tlv_attr_get_string - Retrieve string value from result
* @attr: Attribute to retrieve data from * @attr: Attribute to retrieve data from
* @str: Pointer to an allocated string to store the data * @dst: Pointer to an allocated string to store the data
* @max_size: The maximum size which can be in str * @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, ssize_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *dst,
size_t max_size) size_t dstsize)
{ {
max_size = min_t(size_t, max_size, size_t srclen, len;
(le16_to_cpu(attr->hdr.len) * 4) - sizeof(*attr)); ssize_t ret;
memcpy(str, &attr->value, max_size);
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;
} }
/** /**

View file

@ -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); u64 fbnic_tlv_attr_get_unsigned(struct fbnic_tlv_msg *attr);
s64 fbnic_tlv_attr_get_signed(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, ssize_t fbnic_tlv_attr_get_string(struct fbnic_tlv_msg *attr, char *dst,
size_t max_size); size_t dstsize);
#define get_unsigned_result(id, location) \ #define get_unsigned_result(id, location) \
do { \ do { \