mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-07 22:08:33 -04:00
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:
committed by
Jakub Kicinski
parent
56bcc6ecff
commit
e5cf5107c9
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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 { \
|
||||||
|
|||||||
Reference in New Issue
Block a user