Skip to contentSkip to conversation

Bluetooth: btintel: fix OOB read from short TLV values in version parser

PATCH New Tristan Madani 1 participant 1 message Apr 15 Bluetooth drivers

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 Bluetooth: btintel: fix OOB read from short TLV values in version parser

From: Tristan Madani <[email protected]>

The TLV parser validates that tlv->len fits in the SKB but not that it meets the minimum size required by each type-specific read. Short TLV values cause out-of-bounds reads from SKB data.

Add length checks for types that read fixed-size values (le32, le16, bdaddr_t).

Fixes ca5425e15881 ("Bluetooth: btintel: Add combined setup and shutdown functions")

---
Note: v2 resubmission -- original sent via Gmail had HTML rendering issues. This version uses git send-email for plain-text formatting.

drivers/bluetooth/btintel.c | 16 ++++++++++++++++

 1 file changed, 16 insertions(+)
drivers/bluetooth/btintel.c +19 -0
index XXXXXXX..XXXXXXX 100644
@@ -582,18 +582,34 @@ int btintel_parse_version_tlv(struct hci_dev *hdev,
 		switch (tlv->type) {
 		case INTEL_TLV_CNVI_TOP:
+			if (tlv->len < 4)
+				return -EINVAL;
 			version->cnvi_top = get_unaligned_le32(tlv->val);
 			break;
 		case INTEL_TLV_CNVR_TOP:
+			if (tlv->len < 4)
+				return -EINVAL;
 			version->cnvr_top = get_unaligned_le32(tlv->val);
 			break;
 		case INTEL_TLV_CNVI_BT:
+			if (tlv->len < 4)
+				return -EINVAL;
 			version->cnvi_bt = get_unaligned_le32(tlv->val);
 			break;
 		case INTEL_TLV_CNVR_BT:
+			if (tlv->len < 4)
+				return -EINVAL;
 			version->cnvr_bt = get_unaligned_le32(tlv->val);
 			break;
+		case INTEL_TLV_OTP_BDADDR:
+			if (tlv->len < sizeof(bdaddr_t))
+				return -EINVAL;
+			memcpy(&version->otp_bd_addr, tlv->val, sizeof(bdaddr_t));
+			break;
+		case INTEL_TLV_BUILD_NUM:
+			if (tlv->len < 4)
+				return -EINVAL;
+			version->min_fw_build_nn = tlv->val[0];
+			version->build_num = get_unaligned_le32(tlv->val);
+			break;