CVE-2026-14696 Overview
CVE-2026-14696 is a memory leak vulnerability [CWE-401] in the Zephyr real-time operating system (RTOS) Ethernet bridge implementation. When CONFIG_NET_ETHERNET_BRIDGE is enabled, the function eth_bridge_input_process() in subsys/net/l2/ethernet/bridge/bridge_input.c incorrectly returns NET_OK for frames delivered locally without any consumer taking ownership of the packet. Each affected frame permanently consumes one buffer from the finite RX pool. An attacker on the same L2 segment can flood the device with crafted broadcast or multicast frames to exhaust the RX pool and cause a persistent denial of service until reboot.
Critical Impact
Any unauthenticated device on a bridged Layer 2 segment can permanently exhaust the receive buffer pool by sending broadcast frames with an arbitrary EtherType, rendering the device unable to receive traffic until it is rebooted.
Affected Products
- Zephyr RTOS with CONFIG_NET_ETHERNET_BRIDGE enabled
- Configurations with CONFIG_NET_ETHERNET_FORWARD_UNRECOGNISED_ETHERTYPE set (default when CONFIG_NET_SOCKETS_PACKET is enabled)
- Devices operating as Ethernet bridge members prior to commit 4eb007af465a1d28f2f35d93ecf139cc62c542a7
Discovery Timeline
- 2026-08-31 - CVE-2026-14696 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-14696
Vulnerability Analysis
The vulnerability stems from an incorrect verdict propagation in the Zephyr network stack bridge input path. When a frame arrives on a bridge member interface and must also be delivered to the local stack, eth_bridge_input_process() calls eth_bridge_handle_locally() and returns NET_OK. The helper does not consume the packet. It only invokes bridge_iface_recv() through 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. That function interprets NET_OK 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.
Root Cause
The reproducible leak occurs for frames whose EtherType has no registered Layer 3 handler when CONFIG_NET_ETHERNET_FORWARD_UNRECOGNISED_ETHERTYPE is set. The fall-through L3 dispatch does not overwrite the NET_OK verdict. As a result, ethernet_recv() returns NET_OK and the buffer is never released back to CONFIG_NET_PKT_RX_COUNT. This is a classic missing-release condition tracked as [CWE-401] Missing Release of Memory after Effective Lifetime.
Attack Vector
An attacker with adjacent network access can emit broadcast or multicast frames carrying an arbitrary EtherType. No authentication is required. Each such frame permanently consumes one buffer from the fixed RX pool. A brief broadcast flood exhausts the pool, after which the device can no longer receive traffic. Only a reboot restores functionality. There is no confidentiality or integrity impact.
// Patch to include/zephyr/net/ethernet_bridge.h
// The fix propagates the real net_verdict and returns the destination iface
* @param iface Pointer to bridged iface
* @param pkt Pointer to pkt
+ * @param dst_iface Pointer to pointer to destination iface
*
* @return net_verdict.
*/
-enum net_verdict eth_bridge_input_process(struct net_if *iface, struct net_pkt *pkt);
+enum net_verdict eth_bridge_input_process(struct net_if *iface, struct net_pkt *pkt,
+ struct net_if **dst_iface);
Source: Zephyr commit 4eb007a
// Patch to subsys/net/l2/ethernet/bridge/bridge_input.c
// eth_bridge_handle_locally() now returns net_verdict instead of int
-static int eth_bridge_handle_locally(struct net_if *bridge, struct net_if *orig_iface,
- struct net_pkt *pkt)
+static enum net_verdict eth_bridge_handle_locally(struct net_if *bridge, struct net_if *orig_iface,
+ struct net_pkt *pkt)
{
- enum net_verdict verdict;
-
net_pkt_set_iface(pkt, bridge);
net_pkt_set_orig_iface(pkt, orig_iface);
- if (net_if_l2(bridge)->recv != NULL) {
- verdict = net_if_l2(bridge)->recv(bridge, pkt);
- if (verdict == NET_DROP) {
- return -EIO;
- }
- }
+ NET_ASSERT(net_if_l2(bridge)->recv != NULL);
- return 0;
+ return net_if_l2(bridge)->recv(bridge, pkt);
}
Source: Zephyr commit 4eb007a
Detection Methods for CVE-2026-14696
Indicators of Compromise
- Sudden and sustained drop of CONFIG_NET_PKT_RX_COUNT free buffers to zero without corresponding recovery
- Loss of network responsiveness on a bridged Zephyr device that persists until a reboot
- Unusually high volume of broadcast or multicast frames with uncommon or unregistered EtherType values on the local L2 segment
Detection Strategies
- Instrument the Zephyr network stack to log RX pool occupancy and correlate rapid depletion with inbound frame patterns.
- Deploy network monitoring on the bridged segment to flag broadcast floods with atypical EtherType values.
- Compare firmware builds against Zephyr upstream commit 4eb007af465a1d28f2f35d93ecf139cc62c542a7 to confirm patch presence.
Monitoring Recommendations
- Monitor switch port counters for abnormal broadcast and multicast rates on segments hosting Zephyr bridge devices.
- Track device uptime and unexplained reboots on affected embedded fleets, since reboot is the only recovery path.
- Alert on Zephyr network stack diagnostics that show sustained zero free buffers in the RX pool.
How to Mitigate CVE-2026-14696
Immediate Actions Required
- Update Zephyr-based firmware to a build that includes commit 4eb007af465a1d28f2f35d93ecf139cc62c542a7.
- Inventory all devices with CONFIG_NET_ETHERNET_BRIDGE enabled and prioritize patching those on shared or untrusted L2 segments.
- Rebuild and redeploy any downstream products that vendor Zephyr with the vulnerable bridge implementation.
Patch Information
The fix is available in the upstream Zephyr repository. See the GitHub Security Advisory GHSA-3m4w-wc4v-766q for advisory details and the upstream commit for the code change. The patch 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.
Workarounds
- Disable CONFIG_NET_ETHERNET_BRIDGE in Zephyr builds where bridging is not required.
- Disable CONFIG_NET_ETHERNET_FORWARD_UNRECOGNISED_ETHERTYPE if raw packet sockets are not needed, since this removes the reproducible leak path.
- Restrict affected devices to trusted L2 segments and apply switch-level broadcast storm control to limit frame rates from untrusted hosts.
# Verify the patched commit is present in your Zephyr source tree
cd zephyr
git log --oneline 4eb007af465a1d28f2f35d93ecf139cc62c542a7 -1
# If unpatched, cherry-pick the fix
git fetch origin
git cherry-pick 4eb007af465a1d28f2f35d93ecf139cc62c542a7
# Alternatively, disable bridging in prj.conf if not required
# CONFIG_NET_ETHERNET_BRIDGE=n
# CONFIG_NET_ETHERNET_FORWARD_UNRECOGNISED_ETHERTYPE=n
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

