---
id: "CVE-2026-85034"
kind: "vulnerability"
aliases: ["CVE-2026-85034"]
title: "Zephyr Bluetooth: oversized GATT notifications overflow LE Audio client buffer"
severity: "medium"
cvss: 6.7
epss: null
exploited: false
status: "open"
category: "runtime"
products: []
ecosystems: []
tags: ["bluetooth", "embedded", "iot", "le-audio", "runtime", "zephyr"]
not_affected_if: ["default-config", "no-gatt-client", "no-le-audio"]
published_at: "2026-11-03T14:17:39+00:00"
first_seen_at: "2026-11-03T14:21:08+00:00"
updated_at: "2026-11-03T14:22:02+00:00"
sources: [{"source": "nvd", "url": "https://nvd.nist.gov/vuln/detail/CVE-2026-85034", "first_seen_at": "2026-11-03T14:21:08+00:00"}]
---

# Zephyr Bluetooth: oversized GATT notifications overflow LE Audio client buffer

Zephyr's Bluetooth GATT client accepts notification and indication values longer than the 512-octet specification limit and hands them to subscriber callbacks. In the LE Audio clients this overflows a buffer, which a malicious nearby Bluetooth peer can turn into a controlled write.

_Summary, check and fix written by a model from the sources; labelled as such._

## How to check

- Check whether the build sets `CONFIG_BT_L2CAP_TX_MTU` and `CONFIG_BT_BUF_ACL_RX_SIZE` above the defaults so the ATT MTU exceeds 515 octets.
- Check whether the build enables `CONFIG_BT_BAP_UNICAST_CLIENT` or `CONFIG_BT_BAP_BROADCAST_ASSISTANT` (LE Audio clients).
- Check whether `CONFIG_NET_BUF_HARDENING` is disabled.

## Fix

- Zephyr: a fix rejects notification, indication and multiple-notification values longer than `BT_ATT_MAX_ATTRIBUTE_LEN` in `call_notify_cb_and_maybe_unsubscribe()` in `subsys/bluetooth/host/gatt.c`; the fixed release version is unknown from the sources.

## Timeline

- 2026-11-03T14:21:08+00:00 nvd https://nvd.nist.gov/vuln/detail/CVE-2026-85034

## Documents

- [advisory] Vendor advisory: github.com https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-47vq-phhp-rhxq
- [fix] Patch: github.com https://github.com/zephyrproject-rtos/zephyr/commit/64b1e7447856f635ee8bce9eab7c615da78133b8

## From the sources

The Bluetooth host's GATT client passed the value of a received Handle Value Notification, Handle Value Indication or Multiple Handle Value Notification to bt_gatt_subscribe_params::notify callbacks using only the length derived from the received ATT PDU. bt_att_recv() in subsys/bluetooth/host/att.c validates only a minimum PDU length and does not enforce the negotiated ATT MTU, and the fixed ATT L2CAP channel in subsys/bluetooth/host/l2cap.c applies no rx.mtu check either, so the only ceiling was the ACL reassembly buffer CONFIG_BT_BUF_ACL_RX_SIZE. Values longer than the 512-octet maximum attribute length defined by the Bluetooth Core Specification (Vol 3, Part F, Section 3.2.9) could therefore be handed to subscribers that size their buffers to that documented limit.

A remote peer that a device has connected and subscribed to — a malicious, spoofed or compromised GATT server within radio range — triggers the flaw by sending a notification or indication whose value exceeds 512 octets on a subscribed handle. In the LE Audio unicast client this reaches a concrete out-of-bounds write: unicast_client_ep_notify() in subsys/bluetooth/audio/bap_unicast_client.c copies the notification into the 512-byte att_buf of struct unicast_client with net_buf_simple_add_mem() and no tailroom check whenever length equals bt_audio_get_max_ntf_size(), i.e. the negotiated ATT MTU minus three. notify_handler() in subsys/bluetooth/audio/bap_broadcast_assistant.c has the same shape. Reaching the overflow requires a build whose ATT MTU exceeds 515 octets (CONFIG_BT_L2CAP_TX_MTU and CONFIG_BT_BUF_ACL_RX_SIZE set for full-length attribute support); the shipped defaults are far smaller.

The overflow writes peer-controlled bytes past att_buf directly over the adjacent struct net_buf_simple net_buf — its data, __buf, len and size fields — which the subsequent long-read accumulation then uses as its destination, turning a small linear overflow into a controlled write. net_buf_simple_add() only asserts on insufficient tailroom unless CONFIG_NET_BUF_HARDENING is enabled, and that option is disabled by default, so ordinary production builds perform the copy. Beyond the in-tree LE Audio clients, any application subscriber that sized its receive buffer to the specification's 512-octet limit was exposed to the same overflow.

The fix rejects notification, indication and multiple-notification values longer than BT_ATT_MAX_ATTRIBUTE_LEN in call_notify_cb_and_maybe_unsubscribe() in subsys/bluetooth/host/gatt.c before any subscriber callback is invoked, so no subscriber can be handed more than the specified maximum. Remaining tuples of a multiple handle value notification are still delivered and oversized indications are still confirmed.

---

_Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai_
