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
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
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | fixedDLA-4841-1 · 2026-10-17 · text | 6.1.190-1 | Update 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 13trixie | fixedDSA-6528-1 · 2026-09-29 · text | 6.12.111-1 | Update 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 14forky | fixed | 7.2.7-1 | Update the kernel and reboot. Fixed in 7.2.7-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.7-1 | Update 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.12 | fixedDLA-4817-1 · 2026-10-04 · text | 6.12.111-1~deb12u1 | Update 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
| Introduced | Fixed in | Commit |
|---|---|---|
| 4.9 | 5.10.271 | 55ed97db27bf |
| 4.9 | 5.15.222 | 833ec2788322 |
| 4.9 | 6.1.189 | 38db09804b26 |
| 4.9 | 6.6.158 | 0b3425fd0ecd |
| 4.9 | 6.12.111 | 011e17b5cae1 |
| 4.9 | 6.18.53 | da8c3a7f5d31 |
| 4.9 | 7.2.7 | b39120523475 |
| 4.9 | 7.3 | 78a86d75a70e |
Debian advisories
| Advisory | Date | Shipped to | Debian |
|---|---|---|---|
| DLA-4841-1 | 2026-10-17 | bookworm 6.1.190-1 | tracker |
| DLA-4817-1 | 2026-10-04 | bookworm 6.12.111-1~deb12u1 | tracker |
| DSA-6528-1 | 2026-09-29 | trixie 6.12.111-1 | tracker |
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.