Search Results (245 CVEs found)

CVE Vendors Products Updated CVSS v3.1
CVE-2026-16512 1 Zephyrproject 1 Zephyr 2026-09-19 3.1 Low
gptp_handle_msg() in subsys/net/l2/ethernet/gptp/gptp.c dereferenced the gPTP header returned by GPTP_HDR() and switched on hdr->message_type without first checking that the received frame carries at least sizeof(struct gptp_hdr) (34) bytes of payload. The header accessor gptp_get_hdr() deliberately never fails for a short buffer — it returns pkt->frags->data and leaves validation to its callers — so a truncated frame produced a header pointer covering memory beyond the received data. The per-message-type checks that follow do not compensate: GPTP_VALID_LEN() reduces to len > 60 once the Ethernet header has been pulled, which is false for every fixed-size gPTP message, so GPTP_CHECK_LEN() never rejects a truncated SYNC, FOLLOWUP, PDELAY_RESP or SIGNALING message. The defect is reached by an unauthenticated peer on the same link sending an Ethernet frame with ethertype 0x88F7 to the PTP multicast address on an interface configured as a gPTP port, with CONFIG_NET_GPTP enabled. Because conformant Ethernet pads frames to 60 bytes, a payload shorter than 34 bytes generally requires a link that can deliver sub-minimum frames — for example the native_sim TAP driver (drivers/ethernet/eth_native_tap.c), which forwards whatever length the host device supplies, or a MAC configured to accept undersized frames. The short packet is retained (net_pkt_ref() into rcvd_sync_ptr, rcvd_follow_up_ptr, rcvd_pdelay_resp_ptr or rcvd_announce_ptr) and later parsed by the media-dependent and media-independent state machines in subsys/net/l2/ethernet/gptp/gptp_md.c and subsys/net/l2/ethernet/gptp/gptp_mi.c, which read tens of further bytes and copy some of them (the announce priority vector, hdr->port_id) into state that is subsequently transmitted. Under the default fixed-size buffer allocator (CONFIG_NET_BUF_FIXED_DATA_SIZE, 128-byte fragments) the accesses stay inside the allocated fragment and disclose stale recycled buffer contents; under the experimental CONFIG_NET_BUF_VARIABLE_DATA_SIZE allocator, where fragments are heap-allocated at the exact frame length, they are genuine out-of-bounds reads. There is no write and no availability impact.
CVE-2026-16514 1 Zephyrproject 1 Zephyr 2026-09-19 4.3 Medium
gptp_mi_qualify_announce() in subsys/net/l2/ethernet/gptp/gptp_mi.c walks the Path Trace TLV of a received IEEE 802.1AS Announce message, comparing each clock identity against the local one. The loop bound was taken solely from the attacker-controlled wire field announce->steps_removed (accepted up to 254), never from announce->tlv.len, which is the field that states how many identities the TLV actually carries. Because path_sequence is the flexible member of the wire TLV (struct gptp_path_trace_tlv) and GPTP_ANNOUNCE() yields a raw pointer into the received packet buffer, the memcmp() inside the loop can address memory well past the end of the received frame. The stack's only length validation, GPTP_ANNOUNCE_CHECK_LEN(), requires the received gPTP payload to be exactly 68 + tlv.len bytes — so it does not constrain the loop, it guarantees the data is absent. An unauthenticated attacker on the same Ethernet segment can send a single Announce frame declaring tlv.len = 0 with steps_removed = 254; the frame passes the length check and reception path (net_gptp_recv() → gptp_handle_msg() → gptp_mi_qualify_announce()), which performs no authentication, and the loop then reads 255 entries of 8 bytes each — about 2 KB — beyond the end of the network buffer. The impact is an out-of-bounds read. The bytes read are only used as a memcmp() operand and are never returned to the attacker, so there is no meaningful information disclosure; the practical risk is that the overread crosses a network buffer pool boundary into unmapped or MPU-protected memory and faults the networking RX thread, causing a denial of service. Exposure is limited to builds that enable the opt-in, experimental CONFIG_NET_GPTP (TSN/AVB deployments) and to attackers with layer-2 adjacency, since gPTP frames are sent to a link-local multicast address and are not routed. The fix computes the true entry count as tlv.len / GPTP_CLOCK_ID_LEN and rejects the announce when steps_removed + 1 exceeds it, so the loop can no longer run past the data the packet-length check proved present.
CVE-2026-16515 1 Zephyrproject 1 Zephyr 2026-09-18 4.7 Medium
net_icmpv6_send_error() in subsys/net/ip/icmpv6.c implemented only one of the three RFC 4443 section 2.4 suppression rules (do not answer an ICMPv6 error with an ICMPv6 error). It did not check whether the triggering packet's source address identifies a single node (rule e.6) or whether the packet was sent to a multicast destination (rule e.3, whose only exceptions are Packet Too Big and Parameter Problem Code 2). Of the five call sites, only the port-unreachable path in subsys/net/ip/connection.c carried an equivalent guard of its own; the extension-header, unknown-next-header and fragmentation paths in subsys/net/ip/ipv6.c and subsys/net/ip/ipv6_fragment.c had none. An unauthenticated attacker with access to the same link can exploit this in two ways. Sending a single IPv6 packet to the link-local all-nodes group ff02::1 carrying an unrecognized next-header value, with the source address spoofed to a chosen victim, causes every Zephyr node on the link to emit an ICMPv6 Parameter Problem message to that victim — a reflector with an amplification factor equal to the number of nodes. Alternatively, sending a unicast packet whose source address is a multicast address causes the node to transmit its ICMPv6 error to that multicast address, turning one unicast packet into a link-flooded multicast frame. Packets addressed to ff02::1 are accepted unconditionally by ipv6_input(), and no check rejects a multicast source address, so no special configuration is required. The impact is degraded availability of the shared link and of the reflection victim, together with the ability for the attacker to hide its own address behind the responding nodes. The effect is amplified on constrained mesh links such as 802.15.4/Thread, where link-local multicast is flooded hop by hop. There is no memory-safety consequence: the error packet itself is well formed, it is simply emitted in cases where the protocol forbids it. The fix adds both suppression checks at the single choke point in net_icmpv6_send_error(), before any reply packet is allocated, preserving the RFC-mandated exceptions for NET_ICMPV6_PACKET_TOO_BIG and Parameter Problem Code 2. Note that the IPv4 counterpart net_icmpv4_send_error() in subsys/net/ip/icmpv4.c still checks only for a broadcast destination and retains an equivalent gap for multicast destinations and non-unique sources.
CVE-2026-14986 1 Zephyrproject 1 Zephyr 2026-09-15 6.8 Medium
The ITE it51xxx I2C driver, when operating as an I2C target (slave) in buffer mode (CONFIG_I2C_TARGET + CONFIG_I2C_TARGET_BUFFER_MODE), copies host-supplied write data into the fixed-size data->target_in_buffer inside its target FIFO interrupt handler target_i2c_isr_fifo() in drivers/i2c/i2c_ite_it51xxx.c. The copy loop stores to target_in_buffer[i + data->w_index] and only checks data->w_index against sizeof(data->target_in_buffer) after the write has already completed, so the bounds check cannot prevent the overflow. The running index data->w_index accumulates count bytes on every FIFO-fill interrupt of an ongoing transaction and is reset to zero only on a STOP or timeout condition. An I2C host that streams a single write transaction longer than the buffer (default CONFIG_I2C_TARGET_IT51XXX_MAX_BUF_SIZE = 256 bytes) drives data->w_index past the end of the buffer, and each subsequent host byte is written out of bounds into the adjacent data->target_out_buffer and following static device data. The trigger is a malicious or misbehaving I2C master on the same bus (for example a compromised application processor or a rogue device on an exposed I2C bus); no software privilege on the victim is required and the handler runs in the target's kernel/firmware context. Because both the written values and the overflow length are attacker-controlled, this is an out-of-bounds write that can crash the controller or be shaped toward code execution. The fix adds a pre-write bounds check in target_i2c_fifo_read_to_buf() that aborts and resets the FIFO before any out-of-bounds store.
CVE-2026-15923 1 Zephyrproject 1 Zephyr 2026-09-15 4.6 Medium
The Zephyr SDIO subsystem function sdio_io_rw_extended_helper() in subsys/sd/sdio.c finishes transfers with a byte-I/O loop that uses size = MIN(remaining, func->cis.max_blk_size) as the per-iteration step. The value func->cis.max_blk_size is decoded directly from the SDIO card's CIS FUNCE tuple in sdio_decode_cis() and is not validated. When a card reports a maximum block size of zero, size is always 0, remaining never decreases, and the loop spins forever. The loop is reached from the public SDIO client API used by drivers, including sdio_read_fifo(), sdio_write_fifo(), and the incrementing register read/write helpers, each of which enters the loop while holding the per-card mutex func->card->lock. A card advertising max_blk_size == 0 therefore hangs the calling thread permanently on its first non-block-aligned transfer and never releases the mutex, denying service to the SDIO peripheral (and any subsystem such as Wi-Fi that depends on it) until the device is reset. The malicious value must come from the SDIO card itself, so the defect is exploitable where a removable SDIO/combo card slot lets an attacker insert a crafted or malfunctioning card (a physical attack vector); on boards with a soldered SDIO peripheral it is not attacker-influenceable. There is no memory-safety, confidentiality, or integrity impact — only a permanent availability loss. The fix returns -EIO when func->cis.max_blk_size is zero, before the loop is entered.
CVE-2026-15893 1 Zephyrproject 1 Zephyr 2026-09-14 6.5 Medium
net_if_ipv6_calc_reachable_time() in subsys/net/ip/net_if.c derives a randomized ND reachable time from ipv6->base_reachable_time as min_reachable + sys_rand32_get() % (max_reachable - min_reachable), where min_reachable = base/2 and max_reachable = 3*base/2 using integer division. When base_reachable_time is 1, both min_reachable and the modulus collapse so the function returns 0, and net_if_ipv6_set_reachable_time() stores that 0 into ipv6->reachable_time. The base_reachable_time is attacker-controlled: handle_ra_input() in subsys/net/ip/ipv6_nbr.c accepts the Reachable Time field of an incoming Router Advertisement whenever it is nonzero and <= MAX_REACHABLE_TIME, so a single unauthenticated, link-local RA carrying a Reachable Time of 1 drives the computed reachable time to 0. Router Advertisements are unauthenticated by default and require only adjacency to the target link. When a neighbor is subsequently confirmed reachable, net_ipv6_nbr_set_reachable_timer() reads the value and executes NET_ASSERT(time, "Zero reachable timeout!"). On builds with CONFIG_ASSERT enabled this triggers a fatal kernel assertion — a remote denial of service; on builds without assertions the reachable timer is armed with K_MSEC(0) and fires immediately, forcing reachable neighbors into perpetual re-solicitation (STALE), degrading Neighbor Discovery. The impact is limited to availability; there is no memory-safety, confidentiality, or integrity consequence.
CVE-2026-15924 1 Zephyrproject 1 Zephyr 2026-09-14 5.9 Medium
Zephyr's TLS socket layer in subsys/net/lib/sockets/sockets_tls.c keeps a single process-global array, client_cache, of cached client sessions that is shared by every TLS socket context. The functions that mutate and read it — tls_session_save(), tls_session_get(), tls_session_cache_reset(), and the settings restore handler — allocate, free, and dereference each entry's heap buffer (entry->session). Before the fix these accesses were serialized only by the per-socket context mutex ctx->lock (assigned per socket in ctx_set_lock()), which provides no mutual exclusion between different sockets touching the shared cache. Because CONFIG_NET_SOCKETS_TLS_MAX_CLIENT_SESSION_COUNT defaults to 1, any two concurrent client sockets contend for the same slot. A thread in tls_session_get() reading entry->session inside mbedtls_ssl_session_load() can run concurrently with another thread in tls_session_save() that selects the same entry for reuse and executes mbedtls_free(entry->session) before reallocating — a use-after-free read, and a double-free when two saves evict the same entry. Both corrupt the mbedTLS heap. The cache is reached on ordinary client paths: at connect time via tls_session_store()/tls_session_restore(), and (on main) whenever a TLS 1.3 session ticket arrives during recv()/poll() via tls_session_store_current(). Exploitation requires an application that opts into per-socket client session caching (the TLS_SESSION_CACHE socket option, off by default) and runs concurrent TLS client connections on multiple threads; the timing that opens the window is influenced by the remote peer(s), so a malicious or compromised server can raise session-ticket frequency to widen it. The reliably-demonstrable impact is memory corruption leading to a crash or heap corruption (denial of service). The fix adds a dedicated session_cache_lock mutex taken across every accessor of client_cache, serializing all reads and frees and closing the race.
CVE-2026-16147 1 Zephyrproject 1 Zephyr 2026-09-14 6.8 Medium
The ITE IT82xx2 USB device-controller driver (drivers/usb/udc/udc_it82xx2.c) mishandles multi-packet OUT transfers on non-control endpoints. In work_handler_out() the active transfer buffer is obtained with udc_buf_peek() (which does not dequeue it); when a full max-packet-size packet arrives but the buffer still has tailroom (the transfer is not yet complete), the pre-fix code both re-arms the endpoint to keep filling that same buf via work_handler_xfer_continue() and simultaneously hands the same, still-being-filled buffer to the upper stack with udc_submit_ep_event(). Because udc_submit_ep_event() transfers ownership of the buffer to the USB device stack (usbd_event_carrier() appends &buf->node to uds_ctx->ep_events, after which the class handler processes and net_buf_unref()s it), the driver continues to DMA subsequent host-controlled OUT packets into a buffer the upper stack may already have freed and recycled — a use-after-free write. In addition, since the buffer was never dequeued, the completing packet runs udc_buf_get() on the same object and submits it a second time, appending &buf->node to the event slist twice (singly-linked-list corruption) and causing a double net_buf_unref(). The IT82xx2 is a USB peripheral controller, so the untrusted USB host controls OUT-transfer packetization and can force this path against any non-control OUT endpoint whose queued buffer exceeds one packet — an ordinary bulk/interrupt pattern. The driver and USB device stack run in kernel context above the external host, giving the host a device-side kernel heap-corruption primitive: a reliable denial of service and, because the written bytes are attacker-controlled, plausible corruption of adjacent net_buf pool memory. The vector is physical (USB attach). The fix defers submission until the buffer is completely filled and lets xfer_work_handler() drive continuation, so each OUT buffer is submitted to the upper stack exactly once.
CVE-2026-16148 1 Zephyrproject 1 Zephyr 2026-09-14 4.6 Medium
The ITE it82xx2 USB device-controller driver initialized its bus-suspend detection work with k_work_init_delayable(&priv->suspended_work, suspended_handler) inside it82xx2_enable() (the driver's .enable op) in drivers/usb/udc/udc_it82xx2.c. This work item is scheduled essentially continuously while the USB bus is active: the interrupt handler reschedules it on every SOF frame and suspended_handler() reschedules itself, so its timeout node is normally linked in the kernel timeout list / a workqueue pending queue. k_work_init_delayable() (kernel/work.c) unconditionally overwrites the entire k_work_delayable structure, including its timeout and queue linkage, with no busy check. Because it82xx2_disable() does not cancel the work, a normal disable-then-enable cycle re-runs api->enable() (udc_enable() only rejects a redundant enable, not a re-enable after disable) and re-initializes the still-pending work in place, corrupting the kernel timeout/workqueue linked lists and causing a kernel panic. An external USB host — for example a host performing USB DFU detach (dfu-util --detach) or forcing repeated attach/reset/re-enumeration — drives the udc_disable()/udc_enable() transitions and controls suspend/resume timing, so it can arrange for the suspend work to be pending across a re-enable. This yields an unauthenticated denial of service (kernel panic) reachable across the USB boundary from a removable, physically-connected host, with no confidentiality or integrity impact demonstrated. The fix moves the k_work_init_delayable() call into the one-time preinit function so the work is initialized exactly once, eliminating the re-initialization of an in-use item.
CVE-2026-15891 1 Zephyrproject 1 Zephyr 2026-09-14 7.5 High
The MQTT-SN client keepalive handler process_ping() in subsys/net/lib/mqtt_sn/mqtt_sn.c removes the gateway record after PINGREQ retries are exhausted. It invoked SYS_SLIST_PEEK_HEAD_CONTAINER(&client->gateways, gw, next) but discarded the result. That macro is a pure expression that does not assign to gw, so gw retained its NULL initializer regardless of the list contents. The code then dereferences the NULL gw (gw->gw_id) and passes it to mqtt_sn_gw_destroy(), reaching k_mem_slab_free(&gateways, NULL). With CONFIG_MEM_SLAB_POINTER_VALIDATE enabled this triggers k_panic(); in the default configuration it performs a write through the NULL pointer ((char )mem = slab->free_list;) and corrupts the slab free list. The outcome is a crash/kernel panic or, on targets where address 0 is writable, silent memory-allocator corruption. The vulnerable branch runs whenever the connected MQTT-SN gateway fails to answer keepalive PINGREQs for the configured number of retries. This condition is controlled by the remote peer: a malicious or compromised gateway, or an on-path/adjacent attacker that advertises itself as a gateway and then stops responding (or blackholes the real gateway's PINGRESPs), forces the client into the defect. MQTT-SN runs over UDP and no authentication is required. The impact is a remotely triggerable denial of service (availability) of the affected MQTT-SN client; there is no attacker-controlled data written. The sibling remover process_advertise() uses SYS_SLIST_FOR_EACH_CONTAINER_SAFE and is not affected. The fix assigns the macro's return value to gw.
CVE-2026-15892 1 Zephyrproject 1 Zephyr 2026-09-14 5.3 Medium
The mcumgr SMP settings-management group handlers settings_mgmt_read(), settings_mgmt_write(), and settings_mgmt_delete() in subsys/mgmt/mcumgr/grp/settings_mgmt/src/settings_mgmt.c allocate a key_name buffer (and, for read, a data buffer) via k_malloc() when CONFIG_MCUMGR_GRP_SETTINGS_BUFFER_TYPE_HEAP is enabled, relying on the end: label to k_free() them. When CONFIG_MCUMGR_GRP_SETTINGS_ACCESS_HOOK is also enabled and the application access hook rejects a request by returning status MGMT_CB_ERROR_RC, the handler executed return ret_rc; directly, bypassing end: and leaking the heap allocation on every rejected request. The settings handlers are reachable over the unauthenticated SMP transport (Bluetooth LE, UART, or UDP, depending on product configuration). The access hook is the mechanism applications use to deny unauthorized settings access, and MGMT_CB_ERROR_RC is a common rejection style, so an attacker who can send settings read/write/delete commands that the hook rejects triggers a heap leak on each attempt. Because the leaked memory is never reclaimed until reboot, a sustained stream of rejected requests monotonically exhausts the kernel heap until k_malloc() fails, denying mcumgr service and impacting any other heap consumer on the device — a denial of service. The impact is availability-only; there is no memory corruption or information disclosure. Only configurations that select the heap buffer type, enable the access hook, and register a hook that returns MGMT_CB_ERROR_RC are affected (the default stack buffer type cannot leak).
CVE-2026-15461 1 Zephyrproject 1 Zephyr 2026-09-11 5.3 Medium
The Sierra Wireless HL78xx modem GNSS driver (drivers/modem/hl78xx/, later drivers/modem/vendor_standalone/hl78xx/) embeds a generic struct gnss_nmea0183_match_data match_data inside struct hl78xx_gnss_data. The generic NMEA0183 match helper (drivers/gnss/gnss_nmea0183_match.c) requires that context to be the first member because its callbacks cast user_data directly to struct gnss_nmea0183_match_data . In the affected releases match_data was the second member (after const struct device dev), so it sat at a non-zero offset while gnss_nmea0183_match_init() initialized it at the correct address. The registered NMEA handlers instead pass the whole device data object (data->devices.gnss->data, offset 0), producing an offset-shifted type confusion between where state is initialized and where the parse callbacks read and write it. When NMEA sentences from the GNSS receiver are parsed, the GGA/RMC callbacks write parsed fix data into the wrong location within the struct, and the GSV callback (gnss_nmea0183_match_gsv_callback, active under CONFIG_GNSS_SATELLITES) reads its satellites pointer and bound from the wrong offsets — non-pointer bytes of struct hl78xx_gnss_data — and then writes parsed struct gnss_satellite entries through that bogus pointer. This is a write through an uninitialized/wild pointer with a garbage bound. The NMEA handlers are registered by default (CONFIG_HL78XX_GNSS_SOURCE_NMEA is the default GNSS source) on devices using the HL78xx GNSS. The driver runs in kernel context and the NMEA data originates from the GNSS radio front-end, so a party able to influence the GNSS signal (for example GNSS/GPS spoofing at radio proximity) can drive the kernel-side parser into the faulty write. The most likely impact is a crash (denial of service) because the bogus pointer resolves to a fixed near-NULL value, with adjacent-memory corruption possible on MMU-less targets. Confidentiality is not affected. Exploitation requires the satellites feature to be enabled and active, so attack complexity is high.
CVE-2026-15460 1 Zephyrproject 1 Zephyr 2026-09-10 5.4 Medium
The Bluetooth Classic (BR/EDR) L2CAP receive handler bt_l2cap_br_recv() in subsys/bluetooth/host/classic/l2cap_br.c dispatched inbound data PDUs based only on the destination channel ID, without checking that the target channel had reached the BT_L2CAP_CONNECTED state. A dynamic channel is assigned its RX CID and added to the connection's channel list while still in BT_L2CAP_CONNECTING (and later BT_L2CAP_CONFIG) — before configuration completes and, for PSMs that require security, before the peer is authenticated (l2cap_br_conn_req()). Because the channel is already findable by bt_l2cap_br_lookup_rx_cid() during this window, a remote peer within radio range can send a data PDU addressed to that CID and have it processed on a not-yet-established channel. The dispatch keys off channel fields (BR_CHAN(chan)->rx.mode, rx.mps) that are only initialized during configuration by l2cap_br_conf(); since channel objects are pooled and bt_l2cap_br_chan_del() does not reset rx.mode or the reassembly buffer _sdu, a reused channel can carry stale state into the CONNECTING window and route the frame into the retransmission/flow-control path (bt_l2cap_br_ret_fc_recv()) with stale parameters and a possibly stale _sdu pointer. The impact is delivery of attacker data to upper-layer protocol handlers on a half-open (and possibly unauthenticated) channel, plus operation on stale or partially initialized channel state on reused channel objects — leading to channel/link teardown (denial of service) and, in the stale-_sdu case, a dangling-pointer condition. The fix adds an explicit BR_CHAN(chan)->state < BT_L2CAP_CONNECTED guard that drops any data received before the channel is fully connected.
CVE-2026-14366 1 Zephyrproject 1 Zephyr 2026-09-01 6.4 Medium
The Silicon Labs SiWx917 WiFi driver's transmit callback siwx91x_send() in drivers/wifi/siwx91x/siwx91x_wifi.c frees a network packet it does not own. In the Zephyr TX path the net_pkt is owned by the L2/networking stack; the driver only borrows it to copy the frame bytes into a local net_buf. Before the fix, after transmitting, siwx91x_send() additionally called net_pkt_unref(pkt) on the caller-owned packet, dropping its last reference and returning it to the shared packet pool prematurely. This code path is compiled in by default (CONFIG_WIFI_SILABS_SIWX91X_NET_STACK_NATIVE). The caller, ethernet_send() in subsys/net/l2/ethernet/ethernet.c, keeps using the packet after the driver returns: it reads net_pkt_get_len(pkt), updates TX statistics, and then performs its own net_pkt_unref(pkt). Because the driver already released the packet, these are use-after-free reads followed by a second unref (a double free). When concurrent network activity recycles the freed slab slot between the two unrefs, the trailing unref decrements a different, live packet's reference count and frees it, corrupting the net_pkt pool shared by both the receive and transmit paths. The defect is exercised by ordinary transmission over the native-stack SiWx917 WiFi interface, and an adjacent attacker on the same WiFi network can induce transmissions (for example ARP or ICMP echo replies, or TCP handshakes) to drive the path. The primary observable impact is loss of availability (transmit hangs and crashes from pool corruption), with race-dependent memory corruption of the kernel networking buffer pool. The fix removes the erroneous net_pkt_unref(pkt) from siwx91x_send(); the driver's receive-path unref, which correctly frees a packet the driver itself allocated, is unaffected.
CVE-2026-14697 1 Zephyrproject 1 Zephyr 2026-09-01 6.5 Medium
net_ipv6_send_ns() in subsys/net/ip/ipv6_nbr.c allocates a transmit net_pkt for a Neighbor Solicitation. When it is called with a data packet pending on an unresolved neighbor and that neighbor's pending_queue is already non-empty (an NS is already outstanding), the function appends the data packet and returns early without ever sending the NS via net_send_data() or releasing it with net_pkt_unref(). The freshly allocated NS net_pkt and its attached TX buffers are held only by a local variable and are leaked permanently, never returning to CONFIG_NET_PKT_TX_COUNT / CONFIG_NET_BUF_TX_COUNT. The leaking branch sits on the normal IPv6 transmit path: net_ipv6_prepare_for_send() (called from net_if.c) invokes net_ipv6_send_ns() for any outbound or forwarded IPv6 packet whose next hop is not yet in the neighbor cache. An on-link (adjacent) attacker can drive it deterministically by sending a burst of request packets (for example ICMPv6 echo requests or UDP datagrams) that all spoof a single non-existent on-link source address: the node generates a reply to each, the first reply queues an NS, and every subsequent reply during the roughly three-second INCOMPLETE resolution window takes the leaking branch and loses one TX packet. Router-configured nodes forwarding attacker traffic toward a non-existent on-link host leak identically. Because the leaked packets are never reclaimed and CONFIG_NET_PKT_TX_COUNT defaults to only 4 (14 for Ethernet), a brief low-rate burst exhausts the TX pool. Once exhausted the node can no longer allocate any transmit packet and cannot send TCP/UDP, ARP/ND, or any reply at all, producing a complete and persistent network denial of service that does not self-heal until reboot. The fix releases the unsent NS packet with net_pkt_unref(pkt) before the early return.
CVE-2026-14367 1 Zephyrproject 1 Zephyr 2026-09-01 3.1 Low
The I3C IBI subsystem in drivers/i3c/i3c_ibi_workq.c hands out statically-allocated work nodes through a free-list i3c_ibi_work_nodes_free implemented as a plain sys_slist_t, which provides no synchronization. The allocation helpers (i3c_ibi_work_enqueue, i3c_ibi_work_enqueue_target_irq, i3c_ibi_work_enqueue_hotjoin, i3c_ibi_work_enqueue_controller_request, i3c_ibi_work_enqueue_cb) called sys_slist_get() directly from ISR context, while the workqueue handler i3c_ibi_work_handler() returned nodes with sys_slist_append() from the workqueue thread, with no lock on either side. Because sys_slist_get() and sys_slist_append() are neither atomic nor interrupt-safe, an IBI interrupt that fires while the workqueue thread is mid-append (or a truly parallel access under CONFIG_SMP) races on the shared list. This corrupts the list linkage: a node may be handed to two consumers, a node may be lost, or the head/tail pointers may be left inconsistent so sys_slist_get() returns a stale or garbage pointer. In the double-hand-out case the subsequent memcpy(ibi_node, ibi_work, sizeof(*ibi_node)) overwrites a node still in flight; a garbage pointer turns the same memcpy into an out-of-bounds write. The race is driven by I3C bus traffic — IBIs, hot-joins, and controller-role requests originate from target devices on the bus, and I3C supports hot-joining devices. An attacker controlling an I3C peripheral on the board's chip-to-chip bus can generate high-frequency interrupts timed to collide with the free operation. Exploitation requires physical access to the bus and winning a narrow timing window; the most realistic impact is a crash or hang (denial of service), with memory corruption possible but hard to control. The fix wraps all free-list sys_slist_get()/sys_slist_append() operations in the new ibi_work_alloc()/ibi_work_free() helpers, each guarded by a k_spinlock (ibi_work_lock), closing the race across ISR and thread contexts.
CVE-2026-14368 1 Zephyrproject 1 Zephyr 2026-09-01 5.4 Medium
The LwM2M JSON content formatter's get_string() in subsys/net/lib/lwm2m/lwm2m_rw_json.c copies a parsed JSON string into a caller-supplied buffer and NUL-terminates it. The length guard used if (string_length > buflen), which accepts a string whose length is exactly buflen. After memcpy() fills the whole buffer, buf[string_length] = '\0' then writes one byte past the end of the buffer (CWE-787). The string value and its length are taken directly from the incoming CoAP payload during a LwM2M WRITE: do_write_op_json() parses the payload obtained from coap_packet_get_payload(), and get_string() is invoked from lwm2m_write_handler() (engine_get_string() in subsys/net/lib/lwm2m/lwm2m_message_handling.c) for a LWM2M_RES_TYPE_STRING resource. The destination buf/buflen is either the resource instance's fixed data buffer (res_inst->data_ptr/max_data_len) or the engine validation buffer (msg->ctx->validate_buf). A LwM2M server (the client's DTLS peer) can therefore write a string resource with a value whose length equals the target buffer size and force a one-byte overflow. The overflow is a single out-of-bounds write of the constant byte 0x00 immediately past the resource or validation buffer, corrupting the adjacent byte in memory. It is not an information leak and the written value is fixed, so it is not a direct code-execution primitive, but it can corrupt adjacent state (an adjacent resource value, a length/flag field, or a struct field) and cause data corruption or a crash. Triggering the write is deterministic; the resulting impact depends on memory layout. The fix changes the guard to string_length >= buflen, rejecting the exact-length case and aligning the JSON formatter with the other content formatters (lwm2m_rw_plain_text.c, lwm2m_rw_oma_tlv.c, lwm2m_rw_senml_json.c, lwm2m_rw_cbor.c, lwm2m_rw_senml_cbor.c), which already used the correct boundary check.
CVE-2026-14696 1 Zephyrproject 1 Zephyr 2026-09-01 6.5 Medium
When Ethernet bridging is enabled (CONFIG_NET_ETHERNET_BRIDGE), eth_bridge_input_process() in subsys/net/l2/ethernet/bridge/bridge_input.c decides how each frame received on a bridge member interface is handled. For frames that must also be delivered to the local stack, the code called eth_bridge_handle_locally() and returned NET_OK. That helper does not consume the packet — it only calls bridge_iface_recv() (via virtual_recv()), which returns NET_CONTINUE without taking ownership of pkt. The NET_OK verdict then propagates through ethernet_recv() up to processing_data() in subsys/net/ip/net_core.c, where NET_OK is interpreted as "the packet was consumed, do not free it." Because no consumer actually took ownership, the RX net_pkt is never returned to the pool and is leaked. The concretely reproducible leak occurs for frames whose EtherType has no registered L3 handler when CONFIG_NET_ETHERNET_FORWARD_UNRECOGNISED_ETHERTYPE is set (default y when CONFIG_NET_SOCKETS_PACKET is enabled): the fall-through L3 dispatch does not overwrite the NET_OK verdict, so ethernet_recv() returns NET_OK and the buffer is never released. Any device on a bridged L2 segment can emit broadcast/multicast frames carrying an arbitrary EtherType with no authentication. Each such frame permanently consumes one buffer from the finite RX pool (CONFIG_NET_PKT_RX_COUNT), so a brief broadcast flood exhausts the pool and the device can no longer receive traffic until it is rebooted — a persistent denial of service. There is no confidentiality or integrity impact. The fix makes eth_bridge_handle_locally() propagate the real net_verdict and return NET_CONTINUE for locally-kept frames, writing the bridge interface back through a new dst_iface out-parameter so the packet follows the normal receive path and is unreferenced exactly once.
CVE-2026-13735 1 Zephyrproject 1 Zephyr 2026-09-01 3.7 Low
Zephyr's WireGuard implementation in subsys/net/lib/wireguard/wg_crypto.c mishandled keepalive packets. In wg_process_data_message(), any type-4 transport-data message whose payload was exactly 16 bytes (an empty plaintext plus a bare Poly1305 tag, i.e. a keepalive) was accepted and returned immediately, before wg_decrypt_packet() was ever called. The Poly1305 authentication tag was therefore never verified; the only preceding gates were a cleartext receiver-index lookup (get_peer_keypair_for_index() on the attacker-supplied data_hdr->receiver) and a non-cryptographic keypair validity/expiry check. The path is reachable entirely from the network: inbound UDP on the WireGuard port is dispatched by wg_input() to handle_transport_data() and then wg_process_data_message(). The 32-bit receiver index is transmitted in cleartext in WireGuard handshake and data messages, so an on-path observer learns it directly and an off-path attacker can brute-force it against the UDP port. Given an active receiving-valid session for that index, an attacker could send a 16-byte garbage payload and have it accepted without possessing the session key. On acceptance the unauthenticated message caused the management layer to observe a spoofed NET_EVENT_VPN_CONNECTED signal (setting peer->first_valid and notifying any net_mgmt listener) and incremented the keepalive-RX statistic. The impact is limited to integrity of this status signal: no plaintext is decrypted or injected, no key is disclosed, and the early-return path did not update the peer endpoint or liveness timers, so there is no traffic-injection, session-takeover, or availability consequence. The fix removes the pre-decrypt early return so a 16-byte payload flows through wg_decrypt_packet(), which verifies the Poly1305 tag over the empty plaintext, followed by the existing anti-replay check; only an authenticated, non-replayed message is then recognised as a keepalive. Forged keepalives now fail the tag check and are counted as decrypt failures.
CVE-2026-13734 1 Zephyrproject 1 Zephyr 2026-09-01 6.5 Medium
Zephyr's WireGuard VPN data-plane receive handler wg_process_data_message() in subsys/net/lib/wireguard/wg_crypto.c validated the anti-replay counter too late. After AEAD decryption of a MESSAGE_TRANSPORT_DATA packet succeeded, the code committed several peer-state changes — update_peer_addr() (endpoint roaming update), the keypair->last_rx/peer->last_rx liveness timers, and keypair_update() (promote next→current and destroy the previous keypair) — and only afterward called wg_check_replay(). On a replayed packet the replay check returned -EINVAL, but none of the preceding mutations were rolled back. The AEAD tag authenticates content but not freshness, so a replayed-but-authentic transport packet decrypts correctly. An attacker who captures one valid ciphertext off the wire (an on-path or shared-medium observer) can re-inject it from an arbitrary spoofed source address. Reaching the handler requires no credentials: it is driven directly from inbound UDP datagrams via the dispatch in subsys/net/lib/wireguard/wg.c. Because the state mutations committed before the replay check, the replay repoints the peer endpoint to the attacker-chosen source address (roaming hijack), redirecting the victim's subsequent outbound tunnel traffic until the legitimate peer's next packet re-corrects it; it also prematurely destroys the previous keypair and refreshes the RX liveness timer. The tunnel payload stays encrypted under the session keypair, so this is an integrity/availability impact (traffic redirection and session disruption), not payload disclosure. The fix moves wg_check_replay() to immediately after a successful decrypt, before any peer-state mutation, matching the WireGuard specification and the Linux reference implementation.