OVSWrap (CVE-2026-64531): Linux kernel Open vSwitch datapath 16-bit nla_len wraparound local privilege escalation with public PoC targeting ~800 x86-64 kernel builds — Threadlinqs Intelligence
As of 2026-08-05, OVSWrap (CVE-2026-64531): Linux kernel Open vSwitch datapath 16-bit nla_len wraparound local privilege escalation with public PoC targeting ~800 x86-64 kernel builds is a high-severity vulnerability threat, tracked by Threadlinqs Intelligence with 9 detection rules (Splunk SPL, Microsoft KQL, Sigma) and 23 indicators of compromise.
Threat ID: TL-2026-1887 · Severity: HIGH · CVSS: 7.8 · Status: ACTIVE · Category: VULNERABILITY
Updated: 2026-08-05 · revalidated 1× · latest source
CVE-2026-64531 (OVSWrap) is a memory-corruption local privilege escalation in the Linux kernel's Open vSwitch (OVS) datapath allowing an unprivileged local user to gain root code execution with
CVE-2026-64531 (OVSWrap) is a local privilege escalation vulnerability in the Linux kernel's Open vSwitch (OVS) datapath, discovered and reported by security researcher Asim Manizada. The vulnerability resides in the Netlink action attribute handling within net/openvswitch/flow_netlink.c, where OVS stores internally-generated flow actions as Netlink attributes using the standard nlattr structure. The nla_len field is 16 bits wide, limiting any single nested attribute to 65,535 bytes.
The bug — an unsafe assignment of a 16-bit length without bounds checking — existed for approximately 13 years but was neutralized by a separate 32 KiB cap on the total generated action stream. A commit in March 2025 (a1e64addf3ff, 'net: openvswitch: remove misbehaving actions length check') removed that cap without adding corresponding protection for individual nested attributes, exposing the latent wraparound. The review thread for this change did not address the security consequence of removing the guard.
To trigger the bug, an attacker submits a CLONE action containing hundreds of small conntrack (CT) sub-actions. On x86-64, each conntrack action expands to approximately 164 bytes during internal conversion (struct ovs_conntrack_info containing zone, helper, labels, timeout, template, and NAT state). When the generated nested CLONE action exceeds 65,535 bytes, the 16-bit nla_len field wraps to a small value (e.g., 65,612 mod 65,536 = 76). The kernel's validation passes because it validates the original (small) attribute list before expansion, and the nla_len assignment happens during generation, not as a validation gate.
Later consumers — specifically the flow dump and teardown code paths — trust the wrapped nla_len to determine where the current action ends and the next begins. The parser advances only the wrapped amount (e.g., 76 bytes from the CLONE header), landing at offset +0x004c, which is still inside the first generated conntrack object. Since conntrack labels and timeout names are attacker-controlled bytes, the attacker has already planted forged OVS action headers (OUTPUT, tunnel SET) at exactly this landing position. These are reinterpreted by the kernel as real actions, creating a fundamental mismatch: the kernel parsed one thing and executes a different action stream.
From this mismatch, the PoC constructs three primitives:
1. Kernel pointer leak — A fake OUTPUT action with nla_len=512 causes OVS to dump a 512-byte span from the flow. This span includes kernel pointers from subsequent generated conntrack objects (which contain real pointers to the FTP conntrack helper). By following the helper pointer → owning module → module kobject type pointer, the attacker deduces the randomized kernel base address.
2. Arbitrary kernel read — A fake tunnel SET action with an attacker-chosen tun_dst pointer is placed at the landing point. When OVS dumps the flow, it treats tun_dst as a pointer to real tunnel metadata and serializes fields (TOS, TTL, port, IPv4) from it back to userspace. Each byte read requires one fresh fake SET action using a tun_dst = target_address - field_offset construction.
3. Targeted 32-bit decrement (write primitive) — When OVS frees the forged action, it calls dst_release() on the tun_dst pointer, which decrements the destination's reference-count field at a fixed offset. One flow deletion performs one decrement. By repeatedly creating and deleting flows, the attacker drives fsuid/fsgid from their current value to zero in the target host process's credential structure.
With fsuid and fsgid reduced to zero in a host-side writer process, that process gains effective root access. It writes a passwordless sudo rule (e.g., the user can sudo without a password) to /etc/sudoers.d/ or appends to /etc/sudoers, then launches sudo -n bash to spawn a root shell.
Critically, the exploit requires no heap grooming — all values (kernel symbol offsets, struct sizes, field offsets) are static per kernel build and derivable from
Weaknesses (CWE)
CWE-190, CWE-787, CWE-1300, CWE-130
Target sectors: government administration, finance, health, technology, telecoms, cloud-service-providers, managed-hosting
Target regions: Global
Update History
- 2026-08-05: What changed No escalation of severity/exploitability/status/attribution — the newer report's own record claims exploitability=ACTIVE, but neither its body nor its timeline shows confirmed in-the-wild exploitation (only PoC availability, a
Detections & IOCs
As of 2026-08-26, this threat has 9 detection rule(s) across Splunk SPL, Microsoft KQL and Sigma, and 23 indicator(s) of compromise. Detection query text and full IOC values are available to authenticated users and programmatically via the Threadlinqs MCP server (Purple tier). View plans.
VULNERABILITY, HIGH, threat intelligence, cybersecurity, CVE-2026-64531, T1592, T1082, T1007, T1033, T1059, T1203, T1098, T1548, T1685, T1078