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
 | 
					 * 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 { \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue