data built 2026-10-19T13:16:53Z

Look up another CVE · open CVE-2026-98368 in the interactive tracker

CVE-2026-98368

esp: downgrade zerocopy managed frags before mutating skb frags

7.8 EPSS 0.1% AV:L

Published 2026-10-06 (13 days ago) by the Linux kernel CNA. Subsystem net/ipv4. Debian urgency: not yet assigned.

What to do, per Debian release

Debian's own status for CVE-2026-98368 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source

ReleaseStatus VersionWhat this means
Debian 12bookwormfixedDLA-4841-1 · 2026-10-17 · text6.1.190-1Update the kernel and reboot. DLA-4841-1 shipped the fix on 2026-10-17, in 6.1.190-1. A running kernel keeps the old code until the machine restarts.
Debian 13trixiefixedDSA-6568-1 · 2026-10-16 · text6.12.113-1Update the kernel and reboot. DSA-6568-1 shipped the fix on 2026-10-16, in 6.12.113-1. A running kernel keeps the old code until the machine restarts.
Debian 14forkyfixed7.2.8-1Update the kernel and reboot. Fixed in 7.2.8-1. A running kernel keeps the old code until the machine restarts.
Debian unstablesidfixed7.2.8-1Update the kernel and reboot. Fixed in 7.2.8-1. A running kernel keeps the old code until the machine restarts.

The vulnerability

What the bug is

On the out-of-place output path (esp->inplace == false) ESP rewrites the skb frag array: esp_output_head() appends a trailer frag and esp_output_tail() replaces the frags with a destination page, both referenced with get_page(). When the skb carries zerocopy managed frags (SKBFL_MANAGED_FRAG_REFS) the payload frags are owned by the ubuf and must not be referenced or unreferenced individually, but ESP mutates the frag array without ever downgrading the skb. This breaks the managed-frag invariant two ways: - esp_ssg_unref() walks the source scatterlist and drops a page reference for every frag, including the ubuf-owned payload frags, pushing their refcount below the GUP pin bias while the pages are still pinned, i.e. a use-after-free of the zerocopy pages; - esp_output_tail() installs its destination page as frag 0 with get_page() but leaves SKBFL_MANAGED_FRAG_REFS set, so skb_release_data() takes the skip_unref branch and never drops that reference, leaking the x->xfrag page at packet rate. Fix this the way every other frag-mutating site does (__ip_append_data(), __ip6_append_data(), tcp_sendmsg_locked()) and call skb_zcopy_downgrade_managed() before ESP touches the frag array: it takes a real reference on each existing frag and clears SKBFL_MANAGED_FRAG_REFS, so the per-frag unref in esp_ssg_unref() and the frag release in skb_release_data() are both balanced and no mixed-ownership frag array is left behind.

Where it lives

The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.

net/ipv4/esp4.c
net/ipv6/esp6.c

What this is
NETWORKING [IPSEC]MAINTAINERS section matched on net/ipv4/esp4* · netdev@vger.kernel.org · Maintained
Kernel module
esp4

Check it on the machine

grep -wE 'CONFIG_INET|CONFIG_INET_ESP' /boot/config-$(uname -r)

Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.

lsmod | grep -w esp4

Prints a line if that module is loaded right now, and nothing if it is not. One that is not loaded can still be loaded later by anything that needs it.

Show whether Debian builds this, per release

Debian builds this as a loadable module. Every release below compiles it as a module on every flavour, so whether the code is in the running kernel depends on whether that module is loaded.

  • bookworm, trixie, forky, sidm
m
a loadable module on every flavour - check lsmod, can be blacklisted
Build switches
CONFIG_INET, CONFIG_INET_ESP
Reads as
all on means the file is compiled; any one off means it is not.

From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages

Signals

Published
2026-10-06 (13 days ago)source
CVSS
7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it
Attack vector
local (AV:L)source
EPSS
0.13%, higher than 2.1% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
not yet assignedsource
Subsystem
net/ipv4

Upstream fixes

The versions the CNA records as introducing and fixing this, and the commit for each. source

IntroducedFixed inCommit
6.06.1.1892359264f377c
6.06.6.15869a768c12398
6.06.12.1126508304ac2c8
6.06.18.546cab554f2c0f
6.07.2.80d0845ee61c5
6.07.3f89416eb3db1

Debian advisories

AdvisoryDateShipped toDebian
DLA-4841-12026-10-17bookworm 6.1.190-1tracker
DSA-6568-12026-10-16trixie 6.12.113-1tracker

Why the CNA scored it this way

Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source

AV:LAttack vector, local
Managed frags are set only by io_uring's io_sg_from_iter() for IORING_OP_SEND_ZC/SENDMSG_ZC with IORING_RECVSEND_FIXED_BUF, so a local process must submit the zerocopy send that esp_output_head()/esp6_output_head() then mutates; a remote peer cannot produce a SKBFL_MANAGED_FRAG_REFS skb.
AC:LAttack complexity, low
The attacker picks every input: an uncloned UDP skb whose data_len+tailen fits in a page and lacks tailroom reliably takes the esp->inplace=false branch, then esp_ssg_unref() drops refs on the ubuf-owned frags. No race or outside state is needed.
PR:LPrivileges required, low
io_uring zerocopy send needs no privilege. The ESP SA/policy can be added inside an unprivileged user+net namespace because xfrm_user_rcv_msg only checks netlink_net_capable(CAP_NET_ADMIN); on a host with IPsec already set up, any local user's traffic hits it.
UI:NUser interaction, none
The attacker does everything with their own io_uring ring, registered buffer, socket and (namespaced) xfrm state; no other user has to act.
S:UScope, unchanged
The page refcount underflow and the freed page stay inside the kernel's own authority, so this is a normal local privilege escalation with no VM or sandbox boundary crossed.
C:HConfidentiality impact, high
esp_ssg_unref() pushes the pinned registered-buffer pages' refcount below the GUP pin bias, so the page is freed while io_uring still has it mapped; once reallocated (e.g. as page tables or slab) the attacker can read kernel memory through the stale buffer.
I:HIntegrity impact, high
Writing through the still-registered fixed buffer into the freed and reallocated page is a page-level use-after-free write primitive (Dirty-Pagetable style), enough for arbitrary kernel memory corruption and privilege escalation.
A:HAvailability impact, high
The page UAF leads to bad-page/refcount oopses, and the missing put_page on the x->xfrag page installed by esp_output_tail() leaks memory at packet rate; both can take the system down.