Summary
CVE-2026-43501 is a patch bypass of CVE-2023-2156 (“Route of Death”) in the IPv6 RPL source-routing receive path (ipv6_rpl_srh_rcv). The 2023 fix only closed the final-hop (segments_left == 0) case. The intermediate-hop case was left open, and it is the more interesting one: the same mac_header wrap fires, but instead of an skb_under panic we get a controllable 14-byte OOB write, reachable remotely with a single crafted IPv6 packet.
A short, misaligned OOB write does not sound like much, but with the right heap shaping it is enough to corrupt a TPACKET pg_vec pointer, alias a kernel .text page RW into userspace, and finish at a root shell. We used it to win $10,500 in Google’s kernelCTF.
Impact & exploitability
One crafted IPv6 packet lands a 14-byte, partially controlled OOB write at a fixed, misaligned page offset. The write itself is 100% remote; turning it into LPE may require runs from a local unprivileged process, since the pg_vec step needs CAP_NET_RAW.
- Attacker model: a single crafted IPv6 packet; the full chain runs from a local unprivileged process inside a user + network namespace
- Primitive: a 14-byte, partially controlled OOB write in an almost arbitrary
kmalloc-xcache - Practical impact: splice a kernel
.textaddress into apg_vecpointer, thenmmapthe ring for a writable alias of that read-only code page - End result: arbitrary kernel read/write, kernel shellcode execution, and a root shell
Am I affected?
The receive path is compiled in whenever CONFIG_IPV6 is set; CONFIG_IPV6_RPL_LWTUNNEL only changes the default of the runtime flag. A target is vulnerable if:
- it supports IPv6, and
- its kernel is in the affected range
5.7–7.1(May 2020 to May 2026), and net.ipv6.conf.*.rpl_seg_enabledis1(remotely reachable), or unprivileged{user,net}namespaces are enabled (locally reachable, since a namespace hands you theCAP_NET_ADMINneeded to flip the flag).
Root cause
pskb_expand_head() is called only when segments_left drops to zero, on the assumption that the recompressed SRH can only grow at the final hop. That assumption is wrong. On an intermediate hop, changing which segment is swapped into daddr changes the shared-prefix length with the last segment, which changes CmprE, which changes the recompressed size.
When the recompressed SRH is larger, the following skb_push() leaves less headroom than mac_len. skb_set_mac_header(skb, -skb->mac_len) stores a negative value into the 16-bit skb->mac_header, which wraps to a large offset, and skb_mac_header_rebuild() memmoves mac_len bytes to that wrapped offset, writing before head. With the right packet the write lands 14 bytes at page offset ff2, and its first 6 bytes (an L2 destination MAC we choose) are attacker-controlled.
Reproducer
The full exploit code can be found in our open source security research project, CyberMeowfia.
Exploit
The chain is short:
- prefetch -> leak the KASLR base.
- CVE-2026-43501 -> splice the high bytes of a kernel
.textaddress into a TPACKETpg_vecpointer, keeping its low 16 bits. - pg_vec remap ->
mmap()the corrupted ring so the aliased pointer maps that kernel.textpage RW into userspace, then overwrite a syscall handler with our kernel shellcode. - kernel shellcode -> trigger the matching syscall, set
core_pattern, and finish from userspace.
The full write-up covers the SRH growth math, the mac_header wrap, the heap
shaping into pg_vec, and the kernel .text patching path.
Patch
The upstream fix adds a headroom check, so the SRH is expanded whenever there is not enough room for the rebuilt MAC header, not only at the final hop:
if (unlikely(!hdr->segments_left)) { if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0,chdr_len = sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3);if (unlikely(!hdr->segments_left || skb_headroom(skb) < chdr_len + skb->mac_len)) { if (pskb_expand_head(skb, chdr_len + skb->mac_len, 0,This closes the wrap. It does not preserve the functionality of a crafted packet; we proposed a larger fix that also keeps the metadata intact, but since RPL is barely used, the smaller version is the one that landed upstream. Fixed in Linux 7.1-rc1 and backported on Jun 16, 2026.
Mitigation
Update to a fixed kernel (the latest LTS). There is no site-level workaround: the trigger is a raw IPv6 packet handled inside the kernel, not anything a userspace service can filter. If you cannot patch yet, disabling unprivileged user namespaces removes the local path and keeping rpl_seg_enabled at 0 removes the remote one, but upgrading is the real fix.
Timeline & credit
Found by Nebula Security. We exploited kernelCTF with this bug on Feb 22, 2026 and reported it to security@kernel.org the next day. After a few rounds (the report was first rejected for needing namespaces to trigger), the bug was fixed on Apr 21, 2026 and backported on Jun 16. Google acknowledged the kernelCTF submission and rewarded us $10,500 on Jun 26; this summary and the full write-up went out on Jul 4.