Commit e5cf5107 authored by Lee Trager's avatar Lee Trager Committed by Jakub Kicinski
Browse files

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: default avatarLee Trager <lee@trager.us>
Link: https://patch.msgid.link/20250228191935.3953712-3-lee@trager.us


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 56bcc6ec
Loading
Loading
Loading
Loading
+30 −9
Original line number Diff line number Diff line
@@ -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;
}

/**
+2 −2
Original line number Diff line number Diff line
@@ -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 { \