From nobody Tue Sep 29 04:11:48 2026 Received: from mail-pj1-f43.google.com (mail-pj1-f43.google.com [209.85.216.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 156F638229A for ; Wed, 12 Aug 2026 17:14:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786554887; cv=none; b=Tmtr2D3RvvIyPjRUfC3d4xXer0nKS8h/HZMWSwflZFWFld5DTLk5RaW5aTSvdbwsqgJcIf5i3qwccRSB+nDZb2LfCgQZ1ytmHj8q8+KP45bhKdt3tqTciyoWVgQG/rgwFfgjXsAngFI/Lx3Xg1OQSEuPOxiY62D7LpGZX7M8t+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786554887; c=relaxed/simple; bh=goB+Ed+1d5rnMX/Gf7kXo8+dy16a0MRkPbyjXDFSXgU=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=DjjAlXP8ilvKdo/cKhyn6vQUtOJENX2s7FsdCqF5GGWcW2tukRxEWbNfZt5iBmYIeJb8UZTR7XL836liCiavGWIO5qjyikk7y4/NQvcyHr5wqyOYGUywA3ORwSK91mVchl9EaxxqIb5t1eE1Qm9AZE9C5iiQ8Q5bsMdjIqEC2NQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OT0/UoKX; arc=none smtp.client-ip=209.85.216.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OT0/UoKX" Received: by mail-pj1-f43.google.com with SMTP id 98e67ed59e1d1-38e08baf860so1455481a91.2 for ; Wed, 12 Aug 2026 10:14:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786554885; x=1787159685; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=aRSdyzFIOnj8kEZYFu/H6/Eba3XNB95fFLCi1SUko1I=; b=OT0/UoKXHWtcYQHTiqm68MMtKkDyfcU2JtiajCHJqDDdMMki4zv3OBaGoSTWc6cEK7 q+BE8RWQv6ojaEmUAKGL07EkR94mjfRr8ByUGjvcOWfzkwwN3byj92Nbv+0n8A1cc9eG E2Zy3rLYqr5SefY7vkDOOXgVn6lJv2tJ4dz4x6UBafYRbBwJY26+KTcw0e+x+X2pvR2d A+iyNm7bjloPzX0KQHJV7uywarbfqlt5eMaWgivdNsU2pxZAWI6NWWD+4QZCTBYgPQP3 GSmB425jeop4dCxZVW/1+RUo0DD92uJXgXzxvkkens6X4uIRhQtjObY8VgOJIm4DRowR Ykiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786554885; x=1787159685; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=aRSdyzFIOnj8kEZYFu/H6/Eba3XNB95fFLCi1SUko1I=; b=l+E+2Ct2Xw2xE1Z9w8Pmk4HRhzHDgHqc9BRIoRj78uFGzf/6GbgNv17H1NNEaMmA2T jgEbLYUsDcsl38GCnm9GqZlQiEinTWOLBjmOr3TBjSzdtrFl+d/6jOFdP8gEG/+91ESB MXzNderq8jUmkUz0e3OqkKFtOqw6allqNpHGlTw+THBYnc0vSRKW5HK26qZCWFuIB0WZ xOszqecrEu/J/WZrBdYLeMvl0iI5HUQ9ewzG2JGdSwKmc3+r3rdb9l7QKTMnbvlwnUma PpPr/6Ubx17LNAWGfAjBiLmgHcBG+wwuU/QtcLDcNLyubKRxSqvK51gHnl6HCYk9fI8G dOGg== X-Forwarded-Encrypted: i=1; AHgh+RrOGhSfYX7MfqrL0ZaYG1edAxwk+Jbk51UeSHjkhN1PX6Dq6QoAENDtswAl6d+u2aF9AAd+m4ppl8rZRzU=@vger.kernel.org X-Gm-Message-State: AOJu0YwcvcKhQeRWXnJkCjvoG96YNjgrGc2BBrQNwIzU4iUnWAJh08mA 0hpsrc7461TEd9qx50sWRfdqE4y1BIABy2RQQO9rNYf+HlsoUqY3Rf+CCzW4/A== X-Gm-Gg: AR+sD13QWQjtqiIWJ4uVCi+YoVzk2BM6KlrvWL4Ihx0jNtwkX1pUX5KGdjSCERaNKOx DX1OIsvFBc6QW1o5ytpg9Fe4jSoUN6VYhUdAE389RfP4je2QLYqgzWd9kQKOa5+YWyhQwkR2GyU YujX+rD73Wd7oV5K2EW0rVvEKKfvV2C0gTbG6XwIzD5W/VraDJV+yAl2aFgF7QN/yBr6fboicgw DGzBeyeNEHojFplNl+FNASHLxs+gQ+xqmBYpnaj/pDC+JeIdM030mMsJVKPQeCQ3A7fAewvnnj7 fQv51cer9gnIpfjFvuW5II26PQwDShc+ipPFHOTOxWZRTZ7D3iI4kFztOUGSzU2jgDBgwXYdvAh o/i0XCGKd62g3D59EYwMmjvnz6y5D5SfSx0nJEgnMWxpHopb9rorxZMy/YqbswxV+IGQLsVX8Cp Fk6v79XA9psZOgZLGyecxkBdrw83RVM7HUMpDYX9XOOvufMp96dCM0EIoQTx/UNfSqKTqkHl7mp I3Lh/AYyuDUmMbBsmABUcGfx/QYPdLRuD417Sc3lbQYYk8FidP0M7xjccA3vdwjHUYMbromJm2U j2M8pXYsrQPgUTGvYTPGzN2T5r2CgEa7wqbN1Qk+tTUGRYkiB4YbnWyc0qvbtFwC6YEIh7iVgiv TR2bGNHdSzBknyZPn6t7ZBgAbtcOAld4lDN+njy/s/mKOslPBbUPsZg== X-Received: by 2002:a17:90b:2ecb:b0:36a:5d1f:7b6 with SMTP id 98e67ed59e1d1-39301252d62mr8976148a91.2.1786554885349; Wed, 12 Aug 2026 10:14:45 -0700 (PDT) Received: from localhost.localdomain ([101.251.7.10]) by smtp.gmail.com with ESMTPSA id a92af1059eb24-141245540fesm18150827c88.9.2026.08.12.10.14.42 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 12 Aug 2026 10:14:44 -0700 (PDT) From: Laxman Acharya Padhya To: Luiz Augusto von Dentz , linux-bluetooth@vger.kernel.org Cc: Marcel Holtmann , Tedd Ho-Jeong An , linux-kernel@vger.kernel.org Subject: [PATCH] Bluetooth: btintel: validate version TLV value lengths Date: Wed, 12 Aug 2026 22:59:34 +0545 Message-ID: <20260812171434.82729-1-acharyalaxman8848@gmail.com> X-Mailer: git-send-email 2.51.2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" btintel_parse_version_tlv() verifies that a complete TLV is present in the response, but it does not ensure that the value is long enough for the specific TLV type. A short value can therefore cause an out-of-bounds read through get_unaligned_le16(), get_unaligned_le32(), or memcpy(). The firmware ID is also treated as a NUL-terminated string even though the TLV length is its only boundary. This lets snprintf() read beyond the received response if the value has no NUL terminator. Reject undersized values for all known TLV types, limit the firmware ID conversion to the advertised value length, and propagate parser failures to the caller. Fixes: ca5425e15881 ("Bluetooth: btintel: Add combined setup and shutdown f= unctions") Signed-off-by: Laxman Acharya Padhya Assisted-by: Codex:gpt-5 sparse Reviewed-by: Ali Ahmet Memis --- drivers/bluetooth/btintel.c | 44 +++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index bf567b7c5f00..934775e449db 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -570,12 +570,44 @@ int btintel_version_info_tlv(struct hci_dev *hdev, } EXPORT_SYMBOL_GPL(btintel_version_info_tlv); =20 +static u8 btintel_version_tlv_min_len(u8 type) +{ + switch (type) { + case INTEL_TLV_CNVI_TOP: + case INTEL_TLV_CNVR_TOP: + case INTEL_TLV_CNVI_BT: + case INTEL_TLV_CNVR_BT: + case INTEL_TLV_BUILD_NUM: + case INTEL_TLV_GIT_SHA1: + return sizeof(u32); + case INTEL_TLV_DEV_REV_ID: + case INTEL_TLV_TIME_STAMP: + return sizeof(u16); + case INTEL_TLV_IMAGE_TYPE: + case INTEL_TLV_BUILD_TYPE: + case INTEL_TLV_SECURE_BOOT: + case INTEL_TLV_OTP_LOCK: + case INTEL_TLV_API_LOCK: + case INTEL_TLV_DEBUG_LOCK: + case INTEL_TLV_LIMITED_CCE: + case INTEL_TLV_SBE_TYPE: + return sizeof(u8); + case INTEL_TLV_MIN_FW: + return 3; + case INTEL_TLV_OTP_BDADDR: + return sizeof(bdaddr_t); + default: + return 0; + } +} + int btintel_parse_version_tlv(struct hci_dev *hdev, struct intel_version_tlv *version, struct sk_buff *skb) { /* Consume Command Complete Status field */ - skb_pull(skb, 1); + if (!skb_pull(skb, 1)) + return -EINVAL; =20 /* Event parameters contain multiple TLVs. Read each of them * and only keep the required data. Also, it use existing legacy @@ -595,6 +627,9 @@ int btintel_parse_version_tlv(struct hci_dev *hdev, if (skb->len < tlv->len + sizeof(*tlv)) return -EINVAL; =20 + if (tlv->len < btintel_version_tlv_min_len(tlv->type)) + return -EINVAL; + switch (tlv->type) { case INTEL_TLV_CNVI_TOP: version->cnvi_top =3D get_unaligned_le32(tlv->val); @@ -666,7 +701,7 @@ int btintel_parse_version_tlv(struct hci_dev *hdev, break; case INTEL_TLV_FW_ID: snprintf(version->fw_id, sizeof(version->fw_id), - "%s", tlv->val); + "%.*s", tlv->len, tlv->val); break; default: /* Ignore rest of information */ @@ -685,6 +720,7 @@ static int btintel_read_version_tlv(struct hci_dev *hde= v, { struct sk_buff *skb; const u8 param[1] =3D { 0xFF }; + int err; =20 if (!version) return -EINVAL; @@ -703,10 +739,10 @@ static int btintel_read_version_tlv(struct hci_dev *h= dev, return -EIO; } =20 - btintel_parse_version_tlv(hdev, version, skb); + err =3D btintel_parse_version_tlv(hdev, version, skb); =20 kfree_skb(skb); - return 0; + return err; } =20 /* ------- REGMAP IBT SUPPORT ------- */ --=20 2.51.2