CVE-2026-77685 (GCVE-0-2026-77685)
Vulnerability from cvelistv5 – Published: 2026-11-10 22:07 – Updated: 2026-11-10 22:07| Vendor | Product | Version | CPE status | |
|---|---|---|---|---|
| zephyrproject | zephyr |
Affected:
1.7.0 , < 4.5.0
(semver)
|
guessed |
{
"containers": {
"cna": {
"affected": [
{
"collectionURL": "https://github.com/zephyrproject-rtos/zephyr",
"defaultStatus": "unaffected",
"packageName": "zephyr",
"product": "zephyr",
"programFiles": [
"subsys/bluetooth/host/classic/rfcomm.c",
"subsys/bluetooth/host/rfcomm.c"
],
"programRoutines": [
{
"name": "rfcomm_handle_msg"
},
{
"name": "rfcomm_make_uih_msg"
},
{
"name": "rfcomm_send_test"
}
],
"vendor": "zephyrproject",
"versions": [
{
"lessThan": "4.5.0",
"status": "affected",
"version": "1.7.0",
"versionType": "semver"
}
]
}
],
"descriptions": [
{
"lang": "en",
"value": "The RFCOMM multiplexer control-channel handler in subsys/bluetooth/host/classic/rfcomm.c computed the echo length for a BT_RFCOMM_TEST command as buf-\u003elen - 1 and passed it to rfcomm_send_test(), whose length parameter is a uint8_t. A malformed but FCS-valid UIH frame on DLCI 0 can leave buf-\u003elen == 0 after rfcomm_handle_msg() pulls the two-byte MCC header, so buf-\u003elen - 1 underflows and narrows to 255.\n\nrfcomm_send_test() then copies 255 bytes out of a receive buffer that holds no remaining valid data, and appends them to an outgoing L2CAP PDU allocated with only CONFIG_BT_L2CAP_TX_MTU (253 by default for CONFIG_BT_CLASSIC) bytes of tailroom. The source read runs past the end of the ACL receive buffer into adjacent buffers of the same net_buf pool, and the destination copy overruns the transmit buffer by about eight bytes; net_buf_add_mem() performs no runtime bounds check in ordinary builds, where the underlying __ASSERT_NO_MSG() is compiled out.\n\nThe trigger is a single five-byte RFCOMM frame on the multiplexer control channel, which is processed as soon as the L2CAP channel for PSM 3 is established \u2014 before any DLC exists and independent of RFCOMM session state. bt_rfcomm_init() registers that L2CAP server with .sec_level = BT_SECURITY_L1, which l2cap_br_conn_security() accepts without any link key from a peer that does not claim host Secure Simple Pairing support, so an unpaired BR/EDR device in radio range of a connectable target with CONFIG_BT_RFCOMM enabled (SPP, HFP, HSP, GOEP and similar profiles all enable it) can reach the defect.\n\nThe resulting 255-byte TEST response is transmitted back to the attacker, disclosing roughly 255 bytes of adjacent stack/pool memory \u2014 including the contents of neighbouring receive buffers, which an attacker can prime with earlier packets \u2014 and the accompanying out-of-bounds write corrupts memory following the transmit buffer, which can crash the Bluetooth host. The request is trivially repeatable, so both the disclosure and the corruption can be driven at will.\n\nTwo fixes are needed, and the first on its own does not close the out-of-bounds write. Fix 1 (0040ef781e1d, #115768) strips the FCS byte in rfcomm_recv() and echoes buf-\u003elen, rejecting anything over UINT8_MAX, which removes the underflow and the over-read. But rfcomm_make_uih_msg() still allocates the response with bt_l2cap_create_pdu() and never compares the requested length with the buffer\u0027s tailroom, so a well-formed TEST command carrying a pattern of about 248 bytes or more still builds a response (3-byte frame header, 2-byte message header, pattern, FCS) larger than the 253 bytes available. A pattern that long can only be received when the RFCOMM L2CAP receive MTU (CONFIG_BT_RFCOMM_L2CAP_MTU, which defaults to CONFIG_BT_BUF_ACL_RX_SIZE) exceeds CONFIG_BT_L2CAP_TX_MTU. The plain BR/EDR defaults (200 against 253) cannot reach it, but from v4.3.0 enabling CONFIG_BT_GOEP raises CONFIG_BT_BUF_ACL_RX_SIZE to 264 (265 from v4.4.0), so GOEP builds with only fix 1 applied still overrun the transmit buffer by up to eight bytes. This includes v4.3.2, the last v4.3 release, which carries fix 1 but will not receive fix 2. Fix 2 (214530895dd3, #118293) checks the tailroom on every RFCOMM PDU allocation and closes this residual write."
}
],
"metrics": [
{
"cvssV3_1": {
"baseScore": 8.3,
"baseSeverity": "HIGH",
"vectorString": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H",
"version": "3.1"
},
"format": "CVSS"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-125",
"description": "bounds",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-191",
"description": "bounds",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-787",
"description": "bounds",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-11-10T22:07:41.411Z",
"orgId": "e2e69745-5e70-4e92-8431-deb5529a81ad",
"shortName": "zephyr"
},
"references": [
{
"name": "Fix commit 0040ef781e1d",
"tags": [
"patch"
],
"url": "https://github.com/zephyrproject-rtos/zephyr/commit/0040ef781e1d705066045850782cd8efa5beaa02"
},
{
"name": "Fix commit 214530895dd3",
"tags": [
"patch"
],
"url": "https://github.com/zephyrproject-rtos/zephyr/commit/214530895dd327ef34468fb25e132df6976e927c"
},
{
"name": "GHSA-mhhp-8w67-cggv",
"url": "https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-mhhp-8w67-cggv"
}
],
"title": "Bluetooth Classic RFCOMM: integer underflow in the MCC TEST command handler leads to out-of-bounds read disclosed to the peer and out-of-bounds write",
"x_generator": {
"engine": "cvelib 1.8.0"
}
}
},
"cveMetadata": {
"assignerOrgId": "e2e69745-5e70-4e92-8431-deb5529a81ad",
"assignerShortName": "zephyr",
"cveId": "CVE-2026-77685",
"datePublished": "2026-11-10T22:07:41.411Z",
"dateReserved": "2026-08-21T05:45:00.814Z",
"dateUpdated": "2026-11-10T22:07:41.411Z",
"state": "PUBLISHED"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2",
"vulnerability-lookup:meta": {
"nvd": {
"cve": {
"affected": [
{
"affectedData": [
{
"collectionURL": "https://github.com/zephyrproject-rtos/zephyr",
"defaultStatus": "unaffected",
"packageName": "zephyr",
"product": "zephyr",
"programFiles": [
"subsys/bluetooth/host/classic/rfcomm.c",
"subsys/bluetooth/host/rfcomm.c"
],
"programRoutines": [
{
"name": "rfcomm_handle_msg"
},
{
"name": "rfcomm_make_uih_msg"
},
{
"name": "rfcomm_send_test"
}
],
"vendor": "zephyrproject",
"versions": [
{
"lessThan": "4.5.0",
"status": "affected",
"version": "1.7.0",
"versionType": "semver"
}
]
}
],
"source": "vulnerabilities@zephyrproject.org"
}
],
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "The RFCOMM multiplexer control-channel handler in subsys/bluetooth/host/classic/rfcomm.c computed the echo length for a BT_RFCOMM_TEST command as buf-\u003elen - 1 and passed it to rfcomm_send_test(), whose length parameter is a uint8_t. A malformed but FCS-valid UIH frame on DLCI 0 can leave buf-\u003elen == 0 after rfcomm_handle_msg() pulls the two-byte MCC header, so buf-\u003elen - 1 underflows and narrows to 255.\n\nrfcomm_send_test() then copies 255 bytes out of a receive buffer that holds no remaining valid data, and appends them to an outgoing L2CAP PDU allocated with only CONFIG_BT_L2CAP_TX_MTU (253 by default for CONFIG_BT_CLASSIC) bytes of tailroom. The source read runs past the end of the ACL receive buffer into adjacent buffers of the same net_buf pool, and the destination copy overruns the transmit buffer by about eight bytes; net_buf_add_mem() performs no runtime bounds check in ordinary builds, where the underlying __ASSERT_NO_MSG() is compiled out.\n\nThe trigger is a single five-byte RFCOMM frame on the multiplexer control channel, which is processed as soon as the L2CAP channel for PSM 3 is established \u2014 before any DLC exists and independent of RFCOMM session state. bt_rfcomm_init() registers that L2CAP server with .sec_level = BT_SECURITY_L1, which l2cap_br_conn_security() accepts without any link key from a peer that does not claim host Secure Simple Pairing support, so an unpaired BR/EDR device in radio range of a connectable target with CONFIG_BT_RFCOMM enabled (SPP, HFP, HSP, GOEP and similar profiles all enable it) can reach the defect.\n\nThe resulting 255-byte TEST response is transmitted back to the attacker, disclosing roughly 255 bytes of adjacent stack/pool memory \u2014 including the contents of neighbouring receive buffers, which an attacker can prime with earlier packets \u2014 and the accompanying out-of-bounds write corrupts memory following the transmit buffer, which can crash the Bluetooth host. The request is trivially repeatable, so both the disclosure and the corruption can be driven at will.\n\nTwo fixes are needed, and the first on its own does not close the out-of-bounds write. Fix 1 (0040ef781e1d, #115768) strips the FCS byte in rfcomm_recv() and echoes buf-\u003elen, rejecting anything over UINT8_MAX, which removes the underflow and the over-read. But rfcomm_make_uih_msg() still allocates the response with bt_l2cap_create_pdu() and never compares the requested length with the buffer\u0027s tailroom, so a well-formed TEST command carrying a pattern of about 248 bytes or more still builds a response (3-byte frame header, 2-byte message header, pattern, FCS) larger than the 253 bytes available. A pattern that long can only be received when the RFCOMM L2CAP receive MTU (CONFIG_BT_RFCOMM_L2CAP_MTU, which defaults to CONFIG_BT_BUF_ACL_RX_SIZE) exceeds CONFIG_BT_L2CAP_TX_MTU. The plain BR/EDR defaults (200 against 253) cannot reach it, but from v4.3.0 enabling CONFIG_BT_GOEP raises CONFIG_BT_BUF_ACL_RX_SIZE to 264 (265 from v4.4.0), so GOEP builds with only fix 1 applied still overrun the transmit buffer by up to eight bytes. This includes v4.3.2, the last v4.3 release, which carries fix 1 but will not receive fix 2. Fix 2 (214530895dd3, #118293) checks the tailroom on every RFCOMM PDU allocation and closes this residual write."
}
],
"id": "CVE-2026-77685",
"lastModified": "2026-11-10T22:20:53.843",
"metrics": {
"cvssMetricV31": [
{
"cvssData": {
"attackComplexity": "LOW",
"attackVector": "ADJACENT_NETWORK",
"availabilityImpact": "HIGH",
"baseScore": 8.3,
"baseSeverity": "HIGH",
"confidentialityImpact": "HIGH",
"integrityImpact": "LOW",
"privilegesRequired": "NONE",
"scope": "UNCHANGED",
"userInteraction": "NONE",
"vectorString": "CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:H",
"version": "3.1"
},
"exploitabilityScore": 2.8,
"impactScore": 5.5,
"source": "vulnerabilities@zephyrproject.org",
"type": "Secondary"
}
]
},
"published": "2026-11-10T22:20:53.717",
"references": [
{
"source": "vulnerabilities@zephyrproject.org",
"url": "https://github.com/zephyrproject-rtos/zephyr/commit/0040ef781e1d705066045850782cd8efa5beaa02"
},
{
"source": "vulnerabilities@zephyrproject.org",
"url": "https://github.com/zephyrproject-rtos/zephyr/commit/214530895dd327ef34468fb25e132df6976e927c"
},
{
"source": "vulnerabilities@zephyrproject.org",
"url": "https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-mhhp-8w67-cggv"
}
],
"sourceIdentifier": "vulnerabilities@zephyrproject.org",
"vulnStatus": "Awaiting Analysis",
"weaknesses": [
{
"description": [
{
"lang": "en",
"value": "CWE-125"
},
{
"lang": "en",
"value": "CWE-191"
},
{
"lang": "en",
"value": "CWE-787"
}
],
"source": "vulnerabilities@zephyrproject.org",
"type": "Secondary"
}
]
}
}
}
}
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
How durations are calculated
Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.
Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.
Loading timeline…
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.