In the world of Linux kernel security, we often talk about “deep” bugs. But every once in a while, a vulnerability comes along that redefines what we thought was possible in terms of longevity, complexity, and sheer audacity.
Enter CVE-2026-43456.
Recently disclosed by Yuki Koike (Senior Executive Officer/CTO) and Toda (a part-timer in the Advanced Analysis Section) at GMO Cybersecurity by Ierae, this vulnerability is nothing short of legendary. The underlying buggy code was merged into the Linux kernel in 2007. For nearly 19 years, it sat quietly in the net/bonding subsystem, completely overlooked, entirely exploitable, and waiting in the shadows.
What makes this discovery even more staggering is the exploit’s reliability. Thanks to the unique characteristics of the bug, an attacker can achieve privilege escalation with a success rate of over 99% in under one second. Naturally, this level of stability caught the eye of Google’s kernelCTF, netting the researchers a massive bounty of over $80,000.
In this extremely in-depth technical deep dive, we are going to tear apart CVE-2026-43456. We will explore the root cause, the mind-bending exploit chain involving 329 chained network interfaces, the role of AI in modern root cause analysis, and how a single line of code hid in plain sight for two decades.
The Anatomy of the Bug: A 19-Year Typo
To understand CVE-2026-43456, we first need to understand two fundamental Linux kernel concepts: the sk_buff (skb) and the Bonding driver.
The sk_buff (skb) Structure
In the Linux kernel network stack, packets are represented as sk_buff structures. An skb is essentially a container for packet data, but its memory layout is highly specific.
skb->head skb->data skb->tail skb->end, skb_shinfo(skb)
| | | |
v v v v
+----------------+-----------------+------------------+------------------+
| headroom | packet data | tail room | skb_shared_info |
+----------------+-----------------+------------------+------------------+
skb->head: The beginning of the allocated buffer.skb->data: The beginning of the current packet data.skb->tail: The end of the current packet data.skb->end: The end of the allocated buffer.
Crucially, at the very end of the skb buffer lies the struct skb_shared_info. This structure stores critical metadata about the SKB, such as whether Zero-Copy (zerocopy) is enabled via skb_shared_info::flags.
The Bonding Driver
Bonding is a Linux network feature that allows multiple physical network interfaces (slave devices) to be aggregated into a single logical interface (the bond device). To function transparently, the bond device must handle packet headers exactly as the underlying slave devices do.
The Root Cause: A Single Line of Type Confusion
Here is where the 19-year-old mistake lives. When a bond device is set up based on a slave device, it copies several properties from the slave to the bond. The vulnerable code, located in bond_setup_by_slave, looks like this:
static void bond_setup_by_slave(struct net_device *bond_dev, struct net_device *slave_dev){ bool was_up = !!(bond_dev->flags & IFF_UP); dev_close(bond_dev); bond_dev->header_ops = slave_dev->header_ops; // <--- THE 19-YEAR CULPRIT bond_dev->type = slave_dev->type; bond_dev->hard_header_len = slave_dev->hard_header_len; bond_dev->needed_headroom = slave_dev->needed_headroom; bond_dev->addr_len = slave_dev->addr_len;}
header_ops is a function pointer table used to handle packet headers for specific protocols. Because the bond device is supposed to be transparent, the original developers reasoned: “If the slave uses these header functions, the bond should use them too.”
The Fatal Flaw: Type Confusion At first glance, this seems harmless. However, these header functions don’t just process data; they read and modify the device’s private memory space (dev->priv).
- For a Bond device,
dev->privpoints tostruct bonding. - For a GRE (Generic Routing Encapsulation) tunnel slave,
dev->privpoints tostruct ip_tunnel.
By copying the GRE header_ops to the Bond device, the kernel ends up calling GRE-specific functions on a Bond device. These functions blindly assume the private memory is a struct ip_tunnel, but it’s actually a struct bonding. This is a textbook Type Confusion.
Because the memory layouts of these two structures are completely different, reading or writing to specific offsets results in catastrophic memory corruption.
Why Did It Take 19 Years to Find?
If this bug has been around since 2007, why didn’t it crash servers everywhere? Why didn’t KASAN (Kernel Address Sanitizer) catch it?
The answer lies in the Linux kernel’s memory allocation. The skb buffer is aligned to the page size. Under normal circumstances, when the type confusion causes a buffer overflow, the overflow writes into unused, page-aligned padding at the end of the memory page.
It corrupts nothing of value. There is no crash, no panic, and no security implication. The memory corruption is completely silent.
To actually weaponize this, an attacker must force the kernel into a highly specific state where the skb->data pointer perfectly overlaps with the skb_shared_info structure at the end of the buffer. Achieving this requires a level of mathematical precision in network interface configuration that no human would ever stumble upon by accident.
The Exploit: A Masterclass in Kernel Pwning
The researchers from GMO Cybersecurity didn’t just find the bug; they engineered a flawless exploit chain to bypass modern kernel mitigations like KASLR (Kernel Address Space Layout Randomization). Here is how they turned a silent memory corruption into a one-second root shell.

Step 1: Bypassing KASLR with IP6GRE
To execute arbitrary code, the exploit first needs to know where the kernel is loaded in memory. They achieved this using an IP6GRE (IPv6 GRE) tunnel as the slave device.
Due to the type confusion, the memory offsets of struct bonding and struct ip6_tnl overlap in a very specific way:
- In
struct bonding, the offset0x38containsrecv_probe, a function pointer that points tobond_rcv_validate(a known kernel function). - In
struct ip6_tnl, the offset0x38containsparms.laddr, which holds the IPv6 source address from the network packet.
/* offset | size */ type = struct ip6_tnl {/* 0x0038 | 0x0010 */ struct in6_addr laddr; // IPv6 Source Address.../* offset | size */ type = struct bonding {/* 0x0038 | 0x0008 */ int (*recv_probe)(...); // Kernel Function Pointer
When the IP6GRE header processing function tries to read its local IPv6 address from offset 0x38, it actually reads the recv_probe function pointer. By sending a specifically crafted packet, the attacker can leak the exact memory address of bond_rcv_validate, instantly calculating the kernel’s base address and defeating KASLR.
Step 2: Arbitrary Code Execution via GRE (IPv4)
With KASLR bypassed, the next step is to hijack the Instruction Pointer (RIP). For this, they switch to the IPv4 version of GRE.
The goal is to trick the kernel into calling a fake function pointer. They do this by overwriting the skb_shinfo(skb)->flags field. If they can set the SKBFL_ZEROCOPY_ENABLE flag, the kernel will treat the packet as a Zero-Copy packet. Later in the network stack, the kernel will attempt to clear this state by calling a callback function pointer stored in the ubuf_info structure. By controlling this callback, they achieve Arbitrary Code Execution.
But how do they overwrite skb_shared_info->flags? They trigger the buffer overflow in the ipgre_header() function. Because of the type confusion, the code reads t->hlen (the GRE header length). In a normal GRE tunnel, this is a positive number. But because the memory is actually struct bonding, t->hlen evaluates to 0.
Consequently, skb_push() doesn’t reserve enough space. When the code writes the GRE flags (greh->flags), it writes them directly into the memory space of skb_shared_info->flags. The value written is 0x07ff (derived from gre_tnl_flags_to_gre_flags(0xffff)), which perfectly sets the Zero-Copy flag (SKBFL_ZEROCOPY_ENABLE = BIT(0)).
Step 3: The Magic Number (Chaining 329 Interfaces)
This is where the exploit transitions from clever to absolute genius.
Remember how we said the overflow only matters if skb->data overlaps perfectly with skb_shared_info? This only happens if the kernel’s reserved headroom space, calculated by LL_RESERVED_SPACE(dev), is exactly 0x3ec0 bytes.
How do you force the kernel to allocate exactly 0x3ec0 bytes of headroom? You chain network interfaces.
The researchers created exactly 329 GRE interfaces and chained them together:
- 8 FOU (Foo Over UDP) GRE interfaces: These add
0x20to the header length. - 320 Plain GRE interfaces: These add
0x18to the header length.
As the kernel calculates the needed_headroom for each chained device, the math accumulates.
LL_MAX_HEADERis0x80.- For Plain GRE:
tunnel->hlen = 0x4,t_hlen = 0x18,dev->hard_header_len = 0x18. - For FOU GRE:
tunnel->hlen = 0xc,t_hlen = 0x20,dev->hard_header_len = 0x20.
When the 8 FOU interfaces and 320 plain interfaces are chained, the needed_headroom perfectly sums up to 0x3e98.
When the last GRE is enslaved to the bond, the bond copies these values:
bond->needed_headroom = 0x3e98bond->hard_header_len = 0x18
The kernel then calculates the final reserved space:
LL_RESERVED_SPACE = align_down(0x3eb0, 0x10) + 0x10 = 0x3ec0
This forces the skb buffer allocation to align perfectly, causing skb->data to overlap with skb_shared_info. The overflow lands exactly on the flags, the Zero-Copy callback is triggered, and the attacker gets root.
The Discovery: Syzkaller and the Rise of AI
The complexity of this exploit explains why it went unnoticed for 19 years. Unless you cleverly design a 329-interface chain to hit a mathematical alignment of 0x3ec0, the bug is completely inert.
The vulnerability was initially discovered by accident using syzkaller, the Linux kernel fuzzer. Syzkaller detected a crash, but the crash occurred at the callback invocation – miles away in the execution path from the actual root cause in bond_setup_by_slave.
Performing the Root Cause Analysis (RCA) on this was a monumental task. The researchers revealed a fascinating detail: they used frontier AI models to help trace the execution path backward.
In the first half of 2025, they utilized advanced AI to analyze the kernel code and map the massive distance between the crash site and the 2007 commit. While the researchers noted that AI cannot yet autonomously discover complex vulnerabilities of this nature without human intuition, it proved to be an invaluable co-pilot in untangling the web of kernel networking code. They consider themselves pioneers of the now-common practice of jointly discovering vulnerabilities with AI.
Scope of Impact and Mitigations
CVE-2026-43456 is a critical vulnerability with a massive blast radius.
- Affected Versions: Linux 2.6.24 through 6.12.77.
- Subsystem:
net/bonding - Requirements: The attacker needs
CAP_NET_ADMINprivileges. While this isn’t remote code execution out-of-the-box, in environments with container escapes, unprivileged user namespaces, or local privilege escalation chains,CAP_NET_ADMINis easily attainable.
How to Protect Your Systems
The vulnerability was patched in March 2026 and is fixed in the latest versions of major Linux distributions (kernel 6.12.77 and newer). Updating your kernel is the primary and best mitigation.
If you are in an environment where you cannot immediately patch, you can apply the following workarounds:
1. Disable Unprivileged User Namespaces If you cannot patch, you can prevent unprivileged users from gaining CAP_NET_ADMIN by disabling user namespace cloning:
sysctl -w kernel.unprivileged_userns_clone=0
Note: This will break services like Rootless Docker.
2. Disable the Bonding Module Since the bug resides entirely in the bonding driver, you can simply disable the module. Most distributions load it on demand, so if you don’t use link aggregation, you can blacklist it:
echo "install bonding /bin/false" > /etc/modprobe.d/disable-bonding.confrmmod bonding 2>/dev/null
Final Thoughts
CVE-2026-43456 is a stark reminder of the sheer complexity of the Linux kernel. A single line of code – copying a function pointer table – can lie dormant for two decades, hiding behind page-aligned memory buffers and complex networking abstractions.
The work by Koike and Toda at GMO Cybersecurity by Ierae is a masterclass in modern vulnerability research. It combines deep kernel internals knowledge, mathematical precision in exploit engineering, and the innovative use of AI for root cause analysis.
As kernel mitigations like KASLR and memory sanitizers continue to evolve, attackers are forced to find increasingly complex, multi-stage bugs to bypass them. The era of simple buffer overflows is over; the era of the 329-interface chained type confusion is here.
Originally Reported by Koike. Source – Reporting a Linux kernel zero-day vulnerability that had been overlooked for over 19 years: CVE-2026-43456








