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

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

CVE-2026-97612

net: mpls: clear inner_protocol when the last label is popped

7.8 EPSS 0.2% AV:L

Published 2026-09-25 (24 days ago) by the Linux kernel CNA. Subsystem net/core. Debian urgency: not yet assigned.

What to do, per Debian release

Debian's own status for CVE-2026-97612 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-6528-1 · 2026-09-29 · text6.12.111-1Update the kernel and reboot. DSA-6528-1 shipped the fix on 2026-09-29, in 6.12.111-1. A running kernel keeps the old code until the machine restarts.
Debian 14forkyfixed7.2.7-1Update the kernel and reboot. Fixed in 7.2.7-1. A running kernel keeps the old code until the machine restarts.
Debian unstablesidfixed7.2.7-1Update the kernel and reboot. Fixed in 7.2.7-1. A running kernel keeps the old code until the machine restarts.
Debian 12bookworm · linux-6.12fixedDLA-4817-1 · 2026-10-04 · text6.12.111-1~deb12u1Update the kernel and reboot. DLA-4817-1 shipped the fix on 2026-10-04, in 6.12.111-1~deb12u1. A running kernel keeps the old code until the machine restarts.

The vulnerability

What the bug is

skb_mpls_push() records the pre-encapsulation network header once, gated on !skb->inner_protocol. skb_mpls_pop() never clears that record, so it outlives the encapsulation it describes. Open vSwitch can then re-push MPLS onto a packet whose inner_network_header still points at the older, deeper offset: push a label, pop every label, recirculate (ovs_flow_key_update() re-derives key->eth.type and resets network_header, but leaves inner_*), then push again. ovs_fragment() trusts the record: skb->network_header = skb->inner_network_header; so skb_network_offset() goes negative. The bound check is signed: if (skb_network_offset(skb) > MAX_L2_LEN) a negative offset passes it, and prepare_frag() widens the value: unsigned int hlen = skb_network_offset(skb); memcpy(&data->l2_data, skb->data, hlen); which is a ~4GiB memcpy out of a 30-byte per-CPU buffer. Reproduced on v7.3-rc1. RDX is the truncated length, (unsigned int)(-8): BUG: unable to handle page fault for address: ffffe8ffffc16000 #PF: supervisor write access in kernel mode Oops: 0002 [#1] SMP KASAN NOPTI RIP: 0010:memcpy+0x8/0x20 RDX: 00000000fffffff8 RSI: ffff888105d732db RDI: ffffe8ffffc16000 prepare_frag+0x3df/0x4e0 ovs_fragment+0x589/0x7e0 do_output+0x4ce/0x5e0 do_execute_actions+0x55d2/0x7b30 ovs_execute_actions+0xea/0x450 Same root-cause shape as commit 975b5b067f52 ("ipv6: sr: restore network header before routing and forwarding"): a stale network header offset reaching a consumer that widens it. Here it originates in the MPLS push/pop path. Clear inner_protocol once the packet is no longer MPLS, so a later push re-records the current header. net/sched/act_mpls.c is the only other skb_mpls_pop() caller and gets the same fix; sch_frag.c saves and restores inner_protocol around fragmentation in the same way OVS does.

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/core/skbuff.c

What this is
NETWORKING [GENERAL]MAINTAINERS section matched on net/ · netdev@vger.kernel.org · Maintained
Show whether Debian builds this, per release

Debian builds this code. Every release below compiles the affected file into the kernels it ships.

  • bookworm, trixie, forky, sid, bookworm · linux-6.12y
y
built into the kernel image on every flavour - only a patch removes it

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 Debian linux-config packages

Signals

Published
2026-09-25 (24 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.16%, higher than 5.2% of all CVEssource
CISA KEV
not listedthe KEV catalogue
Debian urgency
not yet assignedsource
Subsystem
net/core

Upstream fixes

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

IntroducedFixed inCommit
4.95.10.27155ed97db27bf
4.95.15.222833ec2788322
4.96.1.18938db09804b26
4.96.6.1580b3425fd0ecd
4.96.12.111011e17b5cae1
4.96.18.53da8c3a7f5d31
4.97.2.7b39120523475
4.97.378a86d75a70e

Debian advisories

AdvisoryDateShipped toDebian
DLA-4841-12026-10-17bookworm 6.1.190-1tracker
DLA-4817-12026-10-04bookworm 6.12.111-1~deb12u1tracker
DSA-6528-12026-09-29trixie 6.12.111-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
The stale inner_network_header comes from OVS flow actions (push_mpls, pop_mpls, recirc, push_mpls) that the attacker installs over the ovs_flow/ovs_packet generic netlink families. No field of a received packet causes the bad offset, so the vector is local netlink rather than the wire.
AC:LAttack complexity, low
The attacker chooses the flow action sequence and the oversized packet that sends do_output into ovs_fragment(). skb_mpls_pop() then deterministically leaves inner_protocol set, and the negative offset always passes the signed MAX_L2_LEN check, so nothing depends on timing or outside state.
PR:LPrivileges required, low
The OVS datapath, vport, flow and packet genl operations use GENL_UNS_ADMIN_PERM with netnsok=true. That means CAP_NET_ADMIN inside an unprivileged user and network namespace (unshare -Urn) is enough to create a datapath, install the flows and execute packets.
UI:NUser interaction, none
No victim action is needed. The attacker installs the flows and injects or sends the packet themselves inside their own namespace.
S:UScope, unchanged
The overflow corrupts memory of the same kernel that performs the check. This is ordinary in-kernel memory corruption and crosses no hypervisor or IOMMU boundary.
C:HConfidentiality impact, high
prepare_frag() turns a negative skb_network_offset() into an unsigned hlen of about 4 GiB and memcpy()s attacker packet bytes past the 30-byte per-CPU ovs_frag_data.l2_data. The write covers exec_level, owner, bh_lock and the per-CPU data that follows, and memory corruption of this kind can be leveraged for information disclosure.
I:HIntegrity impact, high
This is an out-of-bounds write of attacker-controlled skb data into the per-CPU ovs_pcpu_storage and the per-CPU memory after it, including a task_struct pointer (owner) and lock state. The corruption stays in place if the oops happens in process context (OVS_PACKET_CMD_EXECUTE).
A:HAvailability impact, high
The runaway memcpy in prepare_frag() always runs until it hits an unmapped per-CPU page and oopses, as the fix's reproducer shows (write fault in memcpy from prepare_frag/ovs_fragment). The attacker can repeat this at will.