CVE-2026-10641

Published Jun 17, 2026

Last updated a day ago

Overview

Description
Zephyr's Bluetooth Classic Hands-Free Profile (HFP) Hands-Free role parser (subsys/bluetooth/host/classic/hfp_hf.c) contains an out-of-bounds write. During Service Level Connection setup the HF sends AT+CIND=? and parses the AG's +CIND: response in cind_handle(), which assigns a per-entry counter index and calls cind_handle_values() for each list element. cind_handle_values() then wrote hf-ind_table[index] = i without verifying that index is within the 20-element int8_t ind_table[] array of struct bt_hfp_hf. Because the parser places no cap on the number of +CIND: list entries, a remote Attendant Gateway (a malicious, compromised, or spoofed peer the device connects to over Bluetooth) can send a response with more than 20 recognized indicator entries and drive index arbitrarily large, writing a small attacker-positioned value past the array into adjacent struct fields (feature masks, SDP/version state, the calls[] array, work/atomic bookkeeping) and potentially beyond the static connection pool slot. This yields memory corruption and at least denial of service of the Bluetooth host, triggered by a single malformed AT response with no user interaction. The sibling consumer ag_indicator_handle_values() already performed the equivalent bounds check; this commit adds the same index = ARRAY_SIZE(hf-ind_table) guard to close the gap. Affects builds with CONFIG_BT_HFP_HF enabled; introduced with the original HFP HF CIND parser (~v1.7) and present through v4.4.0.
Source
vulnerabilities@zephyrproject.org
NVD status
Analyzed
Products
zephyr

Risk scores

CVSS 3.1

Type
Secondary
Base score
7.1
Impact score
4.2
Exploitability score
2.8
Vector string
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:H
Severity
HIGH

Weaknesses

vulnerabilities@zephyrproject.org
CWE-787

Social media

Hype score
Not currently trending

Configurations

  1. Zephyr's IPv6 Neighbor Discovery send paths (net_ipv6_send_na, net_ipv6_send_ns, net_ipv6_send_rs in subsys/net/ip/ipv6_nbr.c) updated the per-interface ICMP-sent statistics by calling net_pkt_iface(pkt) after net_send_data(pkt) had already returned successfully. On the success path the network stack owns and releases the packet's reference (the L2/driver send unrefs it, e.g. ethernet_send - net_pkt_unref), so for a freshly allocated packet with refcount 1 the net_pkt slab block can be freed before the statistics line runs (synchronously when no TX queue thread is configured, or via a concurrent TX thread otherwise). The subsequent net_pkt_iface(pkt) reads pkt-iface from the freed slab block, and with CONFIG_NET_STATISTICS_PER_INTERFACE enabled that loaded pointer is dereferenced to increment iface-stats.icmp.sent, a use-after-free (CWE-416). If the slab block was reallocated in the meantime the read/increment targets unrelated or attacker-influenced memory, yielding corrupted statistics, a fault/crash (denial of service), or potential limited memory corruption. The vulnerable Neighbor Advertisement path is reachable by any unauthenticated on-link node simply by sending ICMPv6 Neighbor Solicitations to a Zephyr node with native IPv6 enabled (handle_ns_input - net_ipv6_send_na). Affected from v3.3.0 through v4.4.0; the fix uses the already-available iface argument instead of touching the sent packet. Configurations without per-interface statistics dereference only a global counter and are not affected by the memory-safety aspect.CVE-2026-10640
  2. On Xtensa targets with CONFIG_USERSPACE and CONFIG_XTENSA_MMU, the page-table code (arch/xtensa/core/ptables.c) maintains a global list, xtensa_domain_list, of active memory domains using a list node embedded inside the caller-owned struct k_mem_domain. When a domain is destroyed via k_mem_domain_deinit() - arch_mem_domain_deinit(), the page tables are torn down and domain-arch.ptables is set to NULL, but the domain's node was not removed from xtensa_domain_list. The freed/deinitialized domain therefore remained linked into the global list as a dangling pointer into caller-owned storage that may then be freed or reused. Any subsequent arch_mem_map()/arch_mem_unmap() operation (widely invoked by kernel memory-mapping and demand-paging code) traverses the stale node and dereferences domain-ptables: at minimum a NULL pointer dereference causing a fatal MMU exception (denial of service), and if the k_mem_domain storage has been freed or reused, a use-after-free in which a stale/controlled ptables value is dereferenced and written through during the page-table walk (l2_page_table_map writes l1_table[...] and l2_table[...], and xtensa_mmu_compute_domain_regs writes into the domain struct and the L1 table), yielding page-table memory corruption that can undermine userspace isolation. The vulnerable path is reachable only from privileged kernel/supervisor code (k_mem_domain_deinit is not a syscall), not directly from unprivileged user threads or remotely. Affected: Zephyr v4.4.0 (the Xtensa memory-domain de-initialization feature was introduced in commit 3032b58f52d and first shipped in v4.4.0); fixed on main by adding sys_slist_find_and_remove() in arch_mem_domain_deinit(). The Xtensa MPU path is unaffected.CVE-2026-10635