mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
net: fbnic: validate mailbox TLV extents
The mailbox path warns when a message claims more bytes than the descriptor but still parses it. The attribute walkers also validate a child TLV before proving that its declared span fits in the parent remainder. Reject invalid mailbox message extents and bound each child attribute before type-specific validation. Cc: stable+noautosel@kernel.org # assumes malicious PCIe device Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Link: https://patch.msgid.link/20260830142516.38145-1-pengpeng@iscas.ac.cn Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0a1071aa32
commit
c29b37ed7a
|
|
@ -1677,16 +1677,19 @@ static void fbnic_mbx_process_rx_msgs(struct fbnic_dev *fbd)
|
|||
if (!length)
|
||||
goto next_page;
|
||||
|
||||
/* Report descriptors with length greater than page size */
|
||||
if (length > PAGE_SIZE) {
|
||||
/* Report descriptors with invalid message extents. */
|
||||
if (length < sizeof(msg->hdr) || length > PAGE_SIZE) {
|
||||
dev_warn(fbd->dev,
|
||||
"Invalid mailbox descriptor length: %lld\n",
|
||||
length);
|
||||
goto next_page;
|
||||
}
|
||||
|
||||
if (le16_to_cpu(msg->hdr.len) * sizeof(u32) > length)
|
||||
if (!le16_to_cpu(msg->hdr.len) ||
|
||||
le16_to_cpu(msg->hdr.len) * sizeof(u32) > length) {
|
||||
dev_warn(fbd->dev, "Mailbox message length mismatch\n");
|
||||
goto next_page;
|
||||
}
|
||||
|
||||
/* If parsing fails dump contents of message to dmesg */
|
||||
err = fbnic_tlv_msg_parse(fbd, msg, fbnic_fw_tlv_parser);
|
||||
|
|
|
|||
|
|
@ -430,6 +430,10 @@ int fbnic_tlv_attr_parse_array(struct fbnic_tlv_msg *attr, int len,
|
|||
u16 attr_len;
|
||||
int err;
|
||||
|
||||
attr_len = FBNIC_TLV_MSG_SIZE(le16_to_cpu(attr->hdr.len));
|
||||
if (!attr_len || attr_len > len)
|
||||
return -EINVAL;
|
||||
|
||||
if (tlv_attr_id != attr_id)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -443,7 +447,6 @@ int fbnic_tlv_attr_parse_array(struct fbnic_tlv_msg *attr, int len,
|
|||
|
||||
results[i++] = attr;
|
||||
|
||||
attr_len = FBNIC_TLV_MSG_SIZE(le16_to_cpu(attr->hdr.len));
|
||||
len -= attr_len;
|
||||
attr += attr_len;
|
||||
}
|
||||
|
|
@ -476,11 +479,16 @@ int fbnic_tlv_attr_parse(struct fbnic_tlv_msg *attr, int len,
|
|||
|
||||
/* Work through list of attributes, parsing them as necessary */
|
||||
while (len > 0) {
|
||||
int err = fbnic_tlv_attr_validate(attr, tlv_index);
|
||||
u16 attr_id = attr->hdr.type;
|
||||
u16 attr_len;
|
||||
int err;
|
||||
|
||||
attr_len = FBNIC_TLV_MSG_SIZE(le16_to_cpu(attr->hdr.len));
|
||||
if (!attr_len || attr_len > len)
|
||||
return -EINVAL;
|
||||
|
||||
/* Stop parsing on full error */
|
||||
err = fbnic_tlv_attr_validate(attr, tlv_index);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
|
@ -493,7 +501,6 @@ int fbnic_tlv_attr_parse(struct fbnic_tlv_msg *attr, int len,
|
|||
results[attr_id] = attr;
|
||||
}
|
||||
|
||||
attr_len = FBNIC_TLV_MSG_SIZE(le16_to_cpu(attr->hdr.len));
|
||||
len -= attr_len;
|
||||
attr += attr_len;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user