Hidden in 219 unscored kernel CVEs: CVE-2026-52943, an 8.4 local root that may not be present in your kernel at all

CVE heads-upPrivilege escalationLinux kernel

On June 24, 2026 the Linux kernel CVE stream did something it does more and more often: it published 219 CVEs in a single day — and not one of them carried an official NVD severity score. Most are medium or low. But sitting in that wall of unscored line items is CVE-2026-52943, a use-after-free deep in the kernel's core networking code that the upstream maintainers themselves call "reliably exploitable" — "full root privilege escalation from an unprivileged local user on a default kernel configuration." When 219 entries land at once with an empty severity column, that is exactly the kind of thing that coasts past triage.

A single missing line of bookkeeping lets an unprivileged local user free a still-in-use object on the kernel's zero-copy networking path — a reliable local root (KernelScan scores it 8.4 / High; NVD hasn't scored it at all). It is local-only and fixed across every stable tree. The code lives in core networking, so you can't compile it out — yet for an unprivileged user there is exactly one way in: the RDS protocol, gated by the CONFIG_RDS_TCP build option and shipped as an rds module that, as of 2026, most mainstream distributions blacklist by default. So whether this 8.4 is your week's emergency or a documented "not affected" doesn't come from the score — it comes from one concrete check: is that config option built, and is the module present and reachable, in the kernel you actually run?

Why a bug this serious is easy to miss

The dangerous part here is not just the bug — it's the company it keeps. NVD scoring routinely lags days to weeks behind publication, so for a window that can stretch into weeks, all 219 of today's kernel CVEs show up with a blank CVSS field. Triage that sorts by severity has nothing to sort on, and a reliable local-root primitive looks identical to a cosmetic typo fix in that list.

CVE-2026-52943 is the case in point. On the numbers we can compute it sits at 8.4 / High — one of only a handful in the batch an unprivileged user can turn into root — yet it carries the same empty official score as the hundreds around it. The one real limitation works in defenders' favour: it is local-only (AV:L). There is no remote or wormable trigger, so the whole threat reduces to whether untrusted code can run on the machine at all. On a multi-tenant host, a container platform, or anything running customer code, assume yes; on a sealed single-purpose appliance, often no.

The 8.4 / High figure is a KernelScan provisional assessment; NVD had not scored the CVE at publication time. The vector we used is CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.

A two-line fix for a bug that hid for almost a decade

The striking thing about this vulnerability is how small the fix is. The kernel keeps a running tally of how many parts of the system are still using a shared "zero-copy" object — a little ticket the network stack hands out when an application sends data with the zero-copy flag, so the kernel knows when it is finally safe to reclaim the memory. When the tally reaches zero, the object is freed. Two helper routines that relocate network buffers copied the pointer to that ticket into a second buffer but forgot to add one to the tally. The kernel then believed one fewer user was holding the ticket than really was — so it freed the ticket while a buffer still in flight was pointing straight at it. That dangling pointer is the use-after-free.

The entire correction is a two-line snippet, applied identically in each of the two helpers:

if (skb_zcopy(skb)) net_zcopy_get(skb_zcopy(skb));

In plain terms: "if this buffer carries a zero-copy ticket, add one to the tally." That is the whole fix.

So how does a one-line oversight survive for nearly a decade? The helper routines were added back in 2016 (kernel 4.7) for one obscure corner of the networking stack, and the later zero-copy sending feature brought a rule with it: any routine that copies a buffer's bookkeeping must also bump the tally. The common, heavily-used copy routine was taught that rule — but its rarely-travelled twin, the one in this report, was overlooked. It stayed hidden because it is a missing line, not a wrong one: nothing looks broken when you read the code, the neighbouring routine right beside it looks correct, and an absence is invisible unless you are specifically auditing every place the tally ought to be touched. On top of that, the crash only lines up under a very specific sequence of events, and the sanitizer that catches it only fires if the freed object is actually used again. For almost a decade the right combination simply never ran under the right microscope — until someone did a systematic audit of the zero-copy bookkeeping (with AI assistance, the commit notes) and spotted the one copy site still missing the rule.

You can't delete the code — so the question is whether you can reach it

Most kernel CVEs live in a driver or feature you can simply not compile in. This one doesn't: it sits in the core buffer-management code every networked Linux system is built on. There is no config switch that removes it short of removing networking. So at the code level it lands on affected for essentially every kernel in range (every release from 4.7 up to the fixed versions below), and the version-and-config filter that usually narrows a CVE can't narrow this one.

But "the vulnerable code is present" is not the same as "an attacker can reach it." The only path into the buggy routines is a kernel helper called pskb_extract(), and across current kernels only two callers reach it: the RDS-over-TCP socket transport (CONFIG_RDS_TCP) and the IPsec IPTFS mode (CONFIG_XFRM_IPTFS). IPTFS has to be stood up through IPsec, which requires CAP_NET_ADMIN — a privileged operation — so an unprivileged attacker can't establish that path on their own. That leaves exactly one unprivileged way in: RDS.

And here is the part worth acting on. Almost nobody deliberately uses RDS (a niche datacenter messaging protocol), and historically the worry was on-demand autoload: opening an AF_RDS socket asks the kernel to pull in rds.ko — the same pattern behind a decade of kernel privilege-escalation bugs (DCCP, TIPC, earlier RDS flaws). The good news in 2026 is that most mainstream distributions took that lesson: they ship RDS (alongside other rare protocols) on their default module blacklist, so on a stock install of those distros the module is not autoloaded and an unprivileged AF_RDS socket simply fails to bring it in. That narrows "exploitable on a default install" considerably — the realistic exposure is systems that actually use RDS, older or minimal images that predate or omit those blacklists, and anything an admin has explicitly re-enabled. It also reframes the upstream phrase "default kernel configuration": the vulnerable code is built into every distribution kernel (the kernel's own defconfig doesn't even build RDS), but whether an unprivileged user can reach it comes down to that module policy.

The check that actually decides it — not the score. Three concrete questions about the kernel you actually run settle whether this 8.4 can touch you. Is the gate even built? — look for CONFIG_RDS_TCP in your kernel config (grep CONFIG_RDS_TCP /boot/config-$(uname -r)); if it is unset, nothing unprivileged reaches the bug and a minimal, appliance, or hardened build that never enabled RDS is effectively not affected, 8.4 or not. Is the module present and reachable? — if RDS is built as a module (=m), is rds.ko actually shipped in your kernel package, and does your distribution leave it loadable or blacklist it? A module that isn't there, or that an unprivileged process can't bring in, is a path that doesn't exist. Who could even run the trigger? — the attack needs untrusted local code on the box, which a multi-tenant host or container platform has and a sealed single-purpose appliance usually doesn't. Enough "no"s and the headline number is just a number: that presence-and-reachability answer, not the CVSS, is what tells you whether you are racing a clock or patching on the normal cycle.

What might the exploit look like?

We don't have the proof-of-concept; the following is informed speculation from the crash fingerprint published in the commit.

Our read: this is almost certainly not a malicious packet arriving from the network — nothing in the bug is reachable from outside the machine. And, perhaps surprisingly, it is probably not a classic race condition either. It is a deterministic accounting error, and that distinction is the whole reason the author can call it "reliably exploitable": timing races are flaky and often fail, but a miscount happens the same way every single time.

The likely shape is a small unprivileged program that:

  • opens the special sockets that route through the vulnerable path (the crash trace points straight at RDS-over-TCP, talking to itself across the loopback interface);
  • sends data with the zero-copy flag, so the kernel attaches one of those tickets;
  • steers those buffers through the relocate routine that quietly shares the ticket without bumping the tally;
  • then frees buffers and drains the socket's error queue so the tally hits zero and the ticket is freed — while another in-flight buffer still points at it;
  • immediately refills that freed slice of memory with attacker-shaped data, and waits for the kernel to follow the now-dangling pointer — which carries a function pointer the attacker now controls — to hijack execution and climb to root.

In one line: a local, deterministic, heap-grooming use-after-free over loopback — no external traffic, no flaky timing window. Which is also why "no public PoC yet" is only a brief comfort: the recipe is mostly legible from the fix and the crash trace.

Which kernels are fixed, and where

The fix was authored by Minh Nguyen, reviewed by Willem de Bruijn (the MSG_ZEROCOPY maintainer), and merged via netdev in late May 2026 before being backported to every maintained branch. We confirmed each backport commit resolves to the version listed here in our local mirror of the stable trees:

Stable branchFirst fixed version
5.105.10.259
5.155.15.210
6.16.1.176
6.66.6.143
6.126.12.93
6.186.18.35
7.07.0.12
mainline7.1

If you run a kernel on one of these branches at or above the listed version, you already have the fix. Anything older, back to 4.7, is affected.

Mailing-list and PoC status

This went through the normal kernel patch process rather than a coordinated security-list disclosure: the patch was posted and reviewed on netdev/linux-kernel in late May 2026, then merged and backported. It was not discussed as an advisory on oss-security.

A working proof-of-concept demonstrably exists — the KASAN trace in the commit names the triggering task poc — but, as of publication, no public PoC or exploit has been released. That is cold comfort, though: the bug is a one-line missing reference and the published fix is effectively the roadmap. Anyone can diff the carve helpers against pskb_expand_head() and see it. The window in which "no public PoC" is reassuring is likely short.

The real lesson: presence beats severity

CVE-2026-52943 is worth patching, but the story it tells is bigger than one CVE. Kernel vulnerabilities increasingly arrive in big unscored batches, and this one was no anomaly — the days around it tell the real story:

DayNew kernel CVEs
Sat, Jun 200
Sun, Jun 211
Mon, Jun 220
Tue, Jun 230
Wed, Jun 24219
Thu, Jun 25147
Fri, Jun 2647 (so far)

Three near-silent days, then 219, 147 and 47 back to back — more than 400 kernel CVEs in 72 hours, every one still unscored by NVD as it landed. Daily counts updated June 26, 2026.

The official severity that most programs triage on simply isn't there when the batch drops — and even once a number lands, it describes the bug, not your exposure: an 8.4 "reliable local root" in code every kernel ships sounds identical whether the path that reaches it is compiled into your build or was never enabled at all. The signal that separates "patch this week" from "note and move on" isn't the score; it's two concrete questions about your own kernel: is the vulnerable code — and the config option and module that reach it — actually present in my build, and can the attacker it needs even exist on my device?

That is the whole reason KernelScan exists. Upload your .config, pick the version and architecture, and it answers the presence question for you — which symbols are built, which CVE paths they actually reach — while your product's security factors decide whether an unprivileged local attacker is even part of your threat model. For a kernel that never builds CONFIG_RDS_TCP — an appliance, a hardened image, or any stock distribution that keeps the module blacklisted — an 8.4 reliable-root headline becomes a defensible, documented "not affected"; for a build that ships and exposes RDS, it is the week's priority. Same CVE, opposite answers — and the deciding factor was never the empty box NVD shows today, but whether the vulnerable path is present at all.