VYPR
Low severity3.7NVD Advisory· Published Jun 16, 2026· Updated Jun 16, 2026

CVE-2026-10636

CVE-2026-10636

Description

Use-after-free in Zephyr's IGMP send path when net_pkt_iface(pkt) is read after the packet is freed, leading to potential crash or stats corruption.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Use-after-free in Zephyr's IGMP send path when net_pkt_iface(pkt) is read after the packet is freed, leading to potential crash or stats corruption.

Vulnerability

In Zephyr's IPv4 IGMP implementation, the function igmp_send() in subsys/net/ip/igmp.c reads the network interface pointer via net_pkt_iface(pkt) after handing the packet to net_send_data(). On the successful-send path with the default immediate-transmit configuration (NET_TC_TX_COUNT=0), the packet's last reference may be released synchronously by the L2 driver or TX handling, returning the net_pkt slab to the free list. The subsequent net_pkt_iface(pkt) dereferences the freed packet, causing a use-after-free read. If CONFIG_NET_STATISTICS_PER_INTERFACE is enabled, the dangling interface pointer is further dereferenced to update statistics counters. The flaw was introduced with IGMPv2 support and affects releases from v2.6.0 through v4.4.0 [1].

Exploitation

The IGMP send path is reachable without authentication from inbound IPv4 IGMP membership queries addressed to 224.0.0.1 (via net_ipv4_igmp_input -> send_igmp_report/send_igmp_v3_report -> igmp_send), as well as from local multicast join/leave/rejoin operations [1]. An attacker on the local network can send a crafted IGMP membership query to trigger the vulnerable code path. The use-after-free occurs on every successful IGMP report transmission; no special race window is needed for the read, but achieving a controllable write requires the asynchronous TX path plus concurrent slab reuse [1].

Impact

The realistic impact is undefined behavior and potential denial of service due to sporadic crashes or statistics corruption. In the worst case, if the freed slab is reused by another allocation before the dereference, an attacker might achieve a controlled write through the statistics-counter increment, but this depends on specific heap state and timing [1]. The CVSS v3 score is 3.7 (Low), reflecting the difficulty of reliable exploitation beyond a crash.

Mitigation

The fix is implemented in commit 0223e5e ("net: ip: igmp: fix use-after-free"), which caches the interface pointer (struct net_if *iface = net_pkt_iface(pkt)) before calling net_send_data() and uses the cached pointer for statistics updates [2]. The fix is merged into the main branch after v4.4.0; users on affected versions (v2.6.0 through v4.4.0) should apply the patch or update to a fixed release. No workaround is documented. Note that the analogous IPv6 MLD path (mld_send in subsys/net/ip/ipv6_mld.c) retains the same unfixed pattern [1].

AI Insight generated on Jun 16, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

5
0223e5e3ec5e

net: ip: igmp: fix use-after-free

https://github.com/zephyrproject-rtos/zephyrTim PamborApr 10, 2026via nvd-ref
1 file changed · +3 2
  • subsys/net/ip/igmp.c+3 2 modified
    @@ -263,18 +263,19 @@ static int igmp_v3_create_packet(struct net_pkt *pkt, const struct net_in_addr *
     
     static int igmp_send(struct net_pkt *pkt)
     {
    +	__maybe_unused struct net_if *iface = net_pkt_iface(pkt);
     	int ret;
     
     	net_pkt_cursor_init(pkt);
     	net_ipv4_finalize(pkt, NET_IPPROTO_IGMP);
     
     	ret = net_send_data(pkt);
     	if (ret < 0) {
    -		net_stats_update_ipv4_igmp_drop(net_pkt_iface(pkt));
    +		net_stats_update_ipv4_igmp_drop(iface);
     		return ret;
     	}
     
    -	net_stats_update_ipv4_igmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_ipv4_igmp_sent(iface);
     
     	return 0;
     }
    
a96ab665bd57

net: ipv6: nbr: fix use-after-free

https://github.com/zephyrproject-rtos/zephyrTim PamborApr 10, 2026via body-scan-shorthand
1 file changed · +3 3
  • subsys/net/ip/ipv6_nbr.c+3 3 modified
    @@ -1222,7 +1222,7 @@ int net_ipv6_send_na(struct net_if *iface, const struct net_in6_addr *src,
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2158,7 +2158,7 @@ int net_ipv6_send_ns(struct net_if *iface,
     
     	net_ipv6_nbr_unlock();
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2230,7 +2230,7 @@ int net_ipv6_send_rs(struct net_if *iface)
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    
aaed8332a62b

net: ipv6: nbr: fix use-after-free

https://github.com/zephyrproject-rtos/zephyrTim PamborApr 10, 2026via body-scan-shorthand
1 file changed · +3 3
  • subsys/net/ip/ipv6_nbr.c+3 3 modified
    @@ -1222,7 +1222,7 @@ int net_ipv6_send_na(struct net_if *iface, const struct net_in6_addr *src,
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2177,7 +2177,7 @@ int net_ipv6_send_ns(struct net_if *iface,
     
     	net_ipv6_nbr_unlock();
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2249,7 +2249,7 @@ int net_ipv6_send_rs(struct net_if *iface)
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    
3cab8170460f

net: ipv6: nbr: fix use-after-free

https://github.com/zephyrproject-rtos/zephyrTim PamborApr 10, 2026via body-scan-shorthand
1 file changed · +3 3
  • subsys/net/ip/ipv6_nbr.c+3 3 modified
    @@ -1221,7 +1221,7 @@ int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2169,7 +2169,7 @@ int net_ipv6_send_ns(struct net_if *iface,
     
     	net_ipv6_nbr_unlock();
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2241,7 +2241,7 @@ int net_ipv6_send_rs(struct net_if *iface)
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    
ef293d8b5e5d

net: ipv6: nbr: fix use-after-free

https://github.com/zephyrproject-rtos/zephyrTim PamborApr 10, 2026via body-scan-shorthand
1 file changed · +3 3
  • subsys/net/ip/ipv6_nbr.c+3 3 modified
    @@ -1135,7 +1135,7 @@ int net_ipv6_send_na(struct net_if *iface, const struct in6_addr *src,
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2063,7 +2063,7 @@ int net_ipv6_send_ns(struct net_if *iface,
     
     	net_ipv6_nbr_unlock();
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    @@ -2135,7 +2135,7 @@ int net_ipv6_send_rs(struct net_if *iface)
     		goto drop;
     	}
     
    -	net_stats_update_icmp_sent(net_pkt_iface(pkt));
    +	net_stats_update_icmp_sent(iface);
     	net_stats_update_ipv6_nd_sent(iface);
     
     	return 0;
    

Vulnerability mechanics

Root cause

"Use-after-free in igmp_send() where net_pkt_iface(pkt) is called after the packet may have been freed by net_send_data()."

Attack vector

An attacker can trigger the use-after-free by sending an unauthenticated IPv4 IGMP membership query addressed to 224.0.0.1. The inbound packet is dispatched to `net_ipv4_igmp_input`, which calls either `send_igmp_report` or `send_igmp_v3_report`, eventually reaching the vulnerable `igmp_send` function [ref_id=1]. After `igmp_send` calls `net_send_data(pkt)`, the L2 driver or the synchronous TX path (default `NET_TC_TX_COUNT=0`) may free the packet. The subsequent call to `net_pkt_iface(pkt)` then dereferences the freed `net_pkt` slab (a use-after-free read), and with `CONFIG_NET_STATISTICS_PER_INTERFACE` the dangling interface pointer is written to for statistics updates [ref_id=1]. Realistic impact is undefined behavior and potential denial of service; a controllable write requires the asynchronous TX path plus a concurrent slab reuse [ref_id=1].

What the fix does

The fix [patch_id=6189728] moves the `net_pkt_iface(pkt)` call to before `net_send_data(pkt)`, caching the interface pointer in a local variable `iface`. All subsequent stats updates (`net_stats_update_ipv4_igmp_drop` and `net_stats_update_ipv4_igmp_sent`) then use this cached pointer instead of dereferencing the packet after it may have been freed [ref_id=1]. The same pattern was applied to the IPv6 neighbor-discovery send functions (`net_ipv6_send_na`, `net_ipv6_send_ns`, `net_ipv6_send_rs`) in patches [patch_id=6189729], [patch_id=6189730], and [patch_id=6189731], which replace `net_pkt_iface(pkt)` with the existing `iface` function parameter [ref_id=1]. The advisory notes that the analogous IPv6 MLD path (`mld_send` in `subsys/net/ip/ipv6_mld.c`) retains the same unfixed pattern as a residual risk [ref_id=1].

Preconditions

  • configThe target must be running Zephyr versions v2.6.0 through v4.4.0 with IGMPv2 support enabled
  • networkNo authentication required; attacker sends an IPv4 IGMP membership query to 224.0.0.1
  • configThe system must use the default synchronous TX path (NET_TC_TX_COUNT=0) for the free to occur immediately

Generated on Jun 16, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

2

News mentions

0

No linked articles in our index yet.