Kernel CVE Batch Analysis: July 19, 2026 (431 CVEs, none scored by NVD)

CVE triageLinux kernelProduct security

On July 19, 2026, the Linux kernel CVE stream emptied a backlog all at once: 431 kernel CVEs published in a single day — and at the time of this triage, not one of them carried an NVD CVSS score. Every severity label in this post is a KernelScan provisional assessment, computed from the upstream fix and crash fingerprint while the official scoring queue catches up. They exist so product teams have something to sort on today instead of staring at 431 blank severity fields.

The useful question is never “are there 431 CVEs?” The useful question is which of them can reach the product you actually ship — its kernel configuration, its architecture, the interfaces it exposes, and the attacker classes its threat model allows. This post does that sorting, and it spends most of its time on the group that product teams most often underestimate: the local privilege-escalation bugs that sit in code every kernel compiles in.

The batch at a glance

KernelScan’s provisional breakdown for the 431 CVEs is 6 Critical, 122 High, 254 Medium, and 49 Low. The median score is 6.1. None had an NVD CVSS score at analysis time — the entire day’s disclosure is, officially, unscored.

128 land at or above 7.0. They split along the line that maps to product exposure: 33 are remotely reachable (a packet or a peer triggers them), 16 are adjacent-network (Wi‑Fi, Bluetooth, or link-local), and 79 are local — an attacker who can already run unprivileged code on the box. The remote handful gets read first, but the local 79 are the larger story, because a big share of them need no special privilege and no exotic config to reach.

Important: this is early triage. NVD, downstream vendors, and product-specific threat models may later disagree on severity — that is normal and expected. The goal is to separate realistic product exposure from version-string noise while the official scoring queue catches up, not to pre‑empt it. Where a commit itself describes exploitability, we quote it.

The part teams underestimate: local root in code you can’t compile out

Of the 431, roughly 72 carry the signature of a local privilege-escalation primitive — local attack vector, unprivileged attacker, high integrity impact, and a memory-corruption bug class (use-after-free, out-of-bounds write, overflow) that can plausibly be steered toward kernel code execution. Most of the 72 live in optional drivers you may never build. But a hard core of them sit in subsystems that are present in essentially every Linux kernel — keyrings, the mount API, the block layer, UNIX sockets — and require no capability at all. A sealed appliance cannot config-gate these away; the only real gates left are the kernel version and whether the fix is backported.

CVE-2026-63824: keyring pkey heap overflow — the one to open first

This is the cleanest confirmed write primitive in the batch. The commit is blunt — “fix overflow in keyctl_pkey_params_get_2()… can result overflow when a too small buffer is provided.” Any local user calls keyctl() for an asymmetric-key operation with an undersized output buffer; the crypto primitive writes up to its maximum output size into the smaller allocation. It needs no privilege, it is deterministic (no race to win), and the asymmetric-key type is built into virtually every distribution kernel. Present since 4.20. If you triage nothing else local from this batch, triage this one.

Three more that need nothing but an unprivileged syscall

  • CVE-2026-63823 — keyring request-key UAF. Racing KEYCTL_INSTANTIATE_IOV against key destruction dereferences a freed authentication payload. Our assessment: arbitrary kernel read/write, a credible path to root. Unprivileged; the commit spells out the exact concurrency scenario.
  • CVE-2026-64015 — keyring lookup UAF. A missing RCU read-side section lets the garbage collector free a node while it is being traversed. Unprivileged keyring use; the code path has existed since 2.6.12.
  • CVE-2026-64074 — statmount out-of-bounds write. The commit title says it outright: “fix slab out-of-bounds write in statmount_mnt_idmap.” An unprivileged statmount() on an idmapped mount produces a one-byte NULL overwrite past a heap buffer. Narrow, but real, and reachable by anyone on kernels 6.15 and later.

And two more in universal code, needing only a race

  • CVE-2026-64017 — block-layer cached-request UAF. Any process submitting I/O can race a plug flush that frees a request still in use. The block multi-queue layer is in every storage-bearing kernel.
  • CVE-2026-64109 — AF_UNIX stream UAF. A peeking recv() raced against a normal recv() on the same socket pair dereferences a freed buffer. No privilege needed — though the commit is candid that the window is narrow and the deref only bites on kernels 6.5 and later.
Why this group matters: config-reachability is KernelScan’s whole premise, but it cuts both ways. These bugs are the counter-example — you can’t switch off keyrings, the mount API, the block layer, or UNIX sockets. For them the question is not “do I build it?” (you do) but “is my kernel past the fix, and does my product let an untrusted local user run code at all?”

The other local half: one setting decides whether they’re reachable

A second, larger cluster of local Highs lives in the network stack — netfilter, BPF sockmap, raw sockets — and every one of them needs a capability (CAP_NET_ADMIN, CAP_NET_RAW, or CAP_BPF). That sounds like it means “root only,” but on a stock distribution it does not: an unprivileged user can acquire those capabilities inside an unprivileged user namespace. So the reachability of this entire group turns on a single product decision — is unprivileged user-namespace creation allowed?

CVE-2026-64114: raw-socket out-of-bounds write, with the reachability written into the commit

This one is unusually well documented — the upstream commit includes its own reachability note. An IP_HDRINCL raw packet with a header length field below the legal minimum (ihl < 5) slips past validation; a downstream AH/xfrm memcpy() then receives a length close to SIZE_MAX and writes far out of bounds. The commit states the attacker is “any caller with CAP_NET_RAW, including an unprivileged process in a user+net namespace on a kernel with CONFIG_USER_NS=y,” and that it reproduces “inside a rootless Docker container with --cap-add NET_ADMIN on a stock distro kernel.” Deterministic trigger, massive OOB write, present since 2.6.12.

Alongside it: three netfilter table-teardown use-after-frees (CVE-2026-64078, CVE-2026-64077, CVE-2026-63858), two BPF-sockmap memory-safety bugs (CVE-2026-63926, CVE-2026-64025), and a TLS scatterlist off-by-one (CVE-2026-64047). Every one is “arbitrary kernel memory corruption” in our assessment — and every one is gated by that same namespace decision.

The product lever: turning off unprivileged user namespaces (for example kernel.unprivileged_userns_clone=0, or building without CONFIG_USER_NS) moves roughly eight of this batch’s core local-root candidates from “any local user” to “needs real root.” It does not touch the keyring / statmount / block / AF_UNIX group above — those need no capability and are unaffected. Two settings, two very different residual-risk pictures.

The remote Criticals: IPv6 extension-header parsing

If the batch has a remote theme, it is net/ipv6/exthdrs.c. Three of the six Criticals live in IPv6 extension-header processing, all 9.8, all triggered by a crafted packet. Two are in base IPv6 — not a feature you can leave unbuilt:

  • CVE-2026-63924 — IPv6 jumbo hop-by-hop stale pointer. A crafted jumbo option leaves the kernel dereferencing a stale header pointer after the socket buffer is reallocated. Remote, unauthenticated, in code present since 2.6.12. No config knob hides it if the product speaks IPv6.
  • CVE-2026-63922 — IPv6 Home Address Option network-header deref. Same file, same single-packet remote trigger, same near-universal reach on any IPv6-enabled kernel.
  • CVE-2026-64132 — IPv6 IOAM use-after-free. Identical 9.8 severity and remote trigger — but only if CONFIG_IPV6_IOAM6 is built, and IOAM is off in the vast majority of kernels. Same score, opposite product answer. The clearest one-line argument for why config, not severity, is the verdict.

The remaining three Criticals are remote but shape-specific: CVE-2026-63887 (iSCSI target login overflow, only if you export iSCSI), CVE-2026-63993 (VXLAN PMTU UAF, only with overlay networking), and CVE-2026-64055 — a 9.8 in the obscure Cortina Gemini Ethernet driver that virtually no product compiles in. A maximum-severity CVE that, for almost everyone, does not exist.

The other remote cluster: network file servers

For NAS and storage products, the most concentrated exposure is the in-kernel file servers. There are eleven ksmbd (in-kernel SMB server) CVEs, seven of them High and several remotely reachable — SID-descriptor and DACL out-of-bounds reads, compound-session and durable-handle dereferences, a durable-scavenger use-after-free. Alongside them sit nine NFS / nfsd CVEs, five High. Gated by CONFIG_SMB_SERVER and CONFIG_NFSD: if your product serves SMB or NFS this is the headline of the day; if it serves neither, all twenty vanish at the config gate.

The shape of the bugs

This is a memory-safety batch, overwhelmingly. Use-after-free is the single largest class at 81 CVEs, followed by NULL-pointer dereference (36), out-of-bounds reads (39), improper input validation (27), out-of-bounds writes (25), and memory leaks (24). Race conditions add another 13. That dominance of use-after-free is exactly why so many of the local bugs carry High provisional scores: a UAF an unprivileged process can steer is a privilege-escalation primitive, not just a crash.

Where in the kernel they landed

By subsystem the batch is front-loaded on networking and storage — but raw volume is a poor guide to risk. Splitting each domain by severity makes that plain:

CriticalHighMediumLowNetworking556131 47% sevFilesystems2360 38% sevUSB / drivers60 3% sevGraphics / DRM844 18% sevMemory / core621 29% sevStorage / block514 43% sevVirt / KVM611 55% sevOther (misc)1690 18% sev
Figure 2. Bar length is volume; colour is the severity mix; the red figure at right is the High+Critical share. The surprise is that volume and risk barely correlate — USB / driver CVEs are plentiful but almost all Medium (3% severe), Virt / KVM is tiny yet 55% severe, and Networking carries every Critical in the batch.
  • Networking — ~30% (core net, IPv6, netfilter, Wi‑Fi, Bluetooth, tunnels, mesh, vendor NIC drivers). The largest domain, and where every remote Critical lives.
  • Filesystems — ~14% (netfs, ksmbd, NFS, f2fs, ntfs3, ocfs2, 9p, virtiofs, udf).
  • Graphics / DRM — ~10%, heavily AMD GPU, plus msm and v3d.
  • USB — ~5%, then a long tail across IIO sensors, KVM, block, memory management, keyrings, hwmon, sound, and RDMA.

The practical reading: a handful of config and product-factor decisions — do you build IPv6 (almost everyone), serve SMB/NFS (most don’t), allow unprivileged user namespaces, and let untrusted local code run — already sort most of this batch’s real exposure.

Not new code — newly assigned

A meaningful share of the batch is genuinely old code. The keyring lookup UAF and the raw-socket write trace back to 2.6, the AF_UNIX bug to 4.2 — bugs that sat in long-term-support and enterprise kernels for years before receiving a CVE ID. (Treat the raw “introduced in 2.6.12” tags with care: the kernel CNA attaches that initial-commit marker whenever the true origin is unknown, so it overstates how many are literally two decades old — see the version section below for how we separate the two.) The point stands regardless: if your product tracks a stable or LTS branch, “we’re on an older, hardened kernel” is not a reason to skip this batch; a real portion of it predates the branch you forked from.

Which versions are fixed — and who gets left behind

Every one of the 431 fixes lands in mainline and the current stable series (7.0 and 6.18). From there, coverage steps down by branch age. Counting the fixes each stable/LTS branch actually received: 6.12 — 293, 6.6 — 232, 6.1 — 189, 5.15 — 158, 5.10 — 127, and then a cliff: 5.4 — six.

6.122936.62326.11895.151585.101275.464.193← end-of-life: near zero
Figure 1. How many of the batch’s 431 fixes each kernel branch received. Blue = still-maintained; red = end-of-life. Coverage thins with age and then collapses: EOL 5.4 got six, 4.19 three.

A raw “affected” count is a trap here, though, and worth being careful about. Many of these CVEs carry a nominal introduced version of 2.6.12 — the initial Git commit — which the kernel CNA uses when the true origin is unknown. Take that at face value and you would conclude a 5.4 kernel is affected by an iio sensor driver or a drm/amdgpu path that did not exist until 6.x. So we treat a branch as affected only when the fix record confirms the vulnerable code is actually in that lineage — not on the strength of the initial-commit marker. On that basis a supported LTS is in good shape: 5.10 and 5.15 each received a backport for essentially 100% of the CVEs that genuinely reach them. Maintained branches get the fixes.

Running EOL 5.4? Two things are true at once. First, 5.4 genuinely dodges most of this batch: roughly 280 of the 431 (about two-thirds) touch code newer than 5.4 and are simply not present — a real, if accidental, benefit of an old kernel. But of the roughly 100 that do reach 5.4, it received a fix for almost none: the six 5.4 backports in this batch are all for bugs introduced inside 5.4’s own stable series, while the older-code vulnerabilities are stranded. 36 of the stranded are High or Critical, including four rated 9.8 — most importantly the two base-IPv6 header bugs (CVE-2026-63922, CVE-2026-63924) that no IPv6-speaking 5.4 kernel can compile out, plus the iSCSI-target login overflow (CVE-2026-63887). Because 5.4 is end-of-life, none of the 36 will ever receive an upstream fix.

So for a 5.4 product the takeaway is not panic but a shortlist. The batch’s real 5.4 exposure is on the order of 100 CVEs, not 431 — and not the ~140 a naive version match would suggest — and a config gate narrows that further to the subsystems you actually build and expose. What is left is the set that genuinely warrants a plan: migrate to a supported branch (6.1, 6.6, 6.12, or a maintained 5.10 / 5.15), rely on a vendor with extended 5.4 backports, or own the backport yourself. A tractable list, instead of a wall.

Medium and low still matter

The 254 Mediums are not noise. Many are use-after-free and out-of-bounds bugs whose score sits below 7.0 only because the current trigger needs a specific capability or a narrow race window — exactly the conditions a particular product might relax. A Medium that needs CAP_NET_ADMIN today is a different risk on an appliance that hands that capability to a container. Score is a starting point for sorting, not the verdict.

The verdict is per-product, and it has four honest outcomes:

  • Not present: the vulnerable code is not built into your kernel — the config gate settles it.
  • Not reachable: the code is present but the attacker the CVE requires is not part of your product’s threat model.
  • Under investigation: version and configuration match, but product reachability is not yet proven.
  • Mitigated or fixed: the product carries the upstream fix, a downstream backport, or a documented configuration mitigation.

That is the difference between “431 new kernel CVEs” and an answer a product team can defend.

How KernelScan helps with this batch

KernelScan is built for exactly this gap: the first hours after a kernel CVE wave, when NVD is still unscored but product teams need to know what deserves attention now. Upload the kernel .config, select the version and architecture, and KernelScan narrows all 431 to the code your product actually builds — the base-IPv6 Criticals stay, the IOAM one and the Cortina-Gemini one fall away, the SMB/NFS cluster resolves to yes-or-no in one config decision. Then your product’s security factors take over: whether untrusted local users exist, whether unprivileged user namespaces are allowed, whether a remote peer or initiator is in scope. That is what separates the keyring overflow you genuinely cannot compile out from the raw-socket bug your namespace policy already neutralises.

Want to see what that judgement looks like end to end? Our deep dive on CVE-2026-52943 walks the whole path from “core code, can’t compile it out” to a specific, defensible, no-reboot mitigation — the same judgement the local Highs in this batch will need.