Look up another CVE · open CVE-2025-38127 in the interactive tracker
CVE-2025-38127
ice: fix Tx scheduler error handling in XDP callback
Published 2025-07-03 (16 months ago) by the Linux kernel CNA. Subsystem drivers/net. Debian urgency: not yet assigned.
What to do, per Debian release
Debian's own status for CVE-2025-38127 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 | vulnerable | 6.1.190-1 | No fix published anywhere yet, neither in Debian nor upstream for the series bookworm tracks. Watch the Debian tracker page for this CVE. Advisories for bookworm have historically landed a median of 23 days after publication. |
| Debian 13trixie | fixed | 6.12.35-1 | Update the kernel and reboot. Fixed in 6.12.35-1. A running kernel keeps the old code until the machine restarts. |
| Debian 14forky | fixed | 6.12.35-1 | Update the kernel and reboot. Fixed in 6.12.35-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 6.12.35-1 | Update the kernel and reboot. Fixed in 6.12.35-1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
When the XDP program is loaded, the XDP callback adds new Tx queues. This means that the callback must update the Tx scheduler with the new queue number. In the event of a Tx scheduler failure, the XDP callback should also fail and roll back any changes previously made for XDP preparation. The previous implementation had a bug that not all changes made by the XDP callback were rolled back. This caused the crash with the following call trace: [ +9.549584] ice 0000:ca:00.0: Failed VSI LAN queue config for XDP, error: -5 [ +0.382335] Oops: general protection fault, probably for non-canonical address 0x50a2250a90495525: 0000 [#1] SMP NOPTI [ +0.010710] CPU: 103 UID: 0 PID: 0 Comm: swapper/103 Not tainted 6.14.0-net-next-mar-31+ #14 PREEMPT(voluntary) [ +0.010175] Hardware name: Intel Corporation M50CYP2SBSTD/M50CYP2SBSTD, BIOS SE5C620.86B.01.01.0005.2202160810 02/16/2022 [ +0.010946] RIP: 0010:__ice_update_sample+0x39/0xe0 [ice] [...] [ +0.002715] Call Trace: [ +0.002452] <IRQ> [ +0.002021] ? __die_body.cold+0x19/0x29 [ +0.003922] ? die_addr+0x3c/0x60 [ +0.003319] ? exc_general_protection+0x17c/0x400 [ +0.004707] ? asm_exc_general_protection+0x26/0x30 [ +0.004879] ? __ice_update_sample+0x39/0xe0 [ice] [ +0.004835] ice_napi_poll+0x665/0x680 [ice] [ +0.004320] __napi_poll+0x28/0x190 [ +0.003500] net_rx_action+0x198/0x360 [ +0.003752] ? update_rq_clock+0x39/0x220 [ +0.004013] handle_softirqs+0xf1/0x340 [ +0.003840] ? sched_clock_cpu+0xf/0x1f0 [ +0.003925] __irq_exit_rcu+0xc2/0xe0 [ +0.003665] common_interrupt+0x85/0xa0 [ +0.003839] </IRQ> [ +0.002098] <TASK> [ +0.002106] asm_common_interrupt+0x26/0x40 [ +0.004184] RIP: 0010:cpuidle_enter_state+0xd3/0x690 Fix this by performing the missing unmapping of XDP queues from q_vectors and setting the XDP rings pointer back to NULL after all those queues are released. Also, add an immediate exit from the XDP callback in case of ring preparation failure.
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.
drivers/net/ethernet/intel/ice/ice_main.c
- What this is
- INTEL ETHERNET DRIVERSMAINTAINERS section matched on drivers/net/ethernet/intel/*/ · intel-wired-lan@lists.osuosl.org · Maintained
- Kernel module
- ice
Check it on the machine
grep -wE 'CONFIG_ETHERNET|CONFIG_ICE|CONFIG_NET_VENDOR_INTEL' /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 icePrints 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, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.
- bookwormMnot built on amd64/cloud-amd64, arm64/cloud-arm64
- trixieMnot built on amd64/cloud-amd64, arm64/cloud-arm64, armel/rpi
- forky, sidMnot built on amd64/cloud-amd64, arm64/cloud-arm64
- M
- a module where it is built at all; some flavours do not build it
- Build switches
- CONFIG_ETHERNET, CONFIG_ICE, CONFIG_NET_VENDOR_INTEL
- 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
- 2025-07-03 (16 months 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.20%, higher than 9.0% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- not yet assignedsource
- Subsystem
- drivers/net
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 5.5 | 6.6.94 | 1d3c5d0dec67 |
| 5.5 | 6.12.34 | 276849954d7c |
| 5.5 | 6.15.3 | 0e061abaad14 |
| 5.5 | 6.16 | 0153f36041b8 |
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 vulnerable path is entered only through local syscalls — `bpf(BPF_PROG_LOAD)` followed by an `RTM_SETLINK`/`IFLA_XDP_FD` netlink message (or `BPF_LINK_CREATE`) reaching `ice_xdp()`. No remote packet or peer data can trigger the XDP setup callback.
- AC:LAttack complexity, low
- The attacker controls the conditions that make `ice_cfg_vsi_lan()` fail — Tx scheduler nodes are never released once allocated, so repeated queue-count growth via `ethtool -L`, TC/ADQ channels, or VF/SF creation deterministically exhausts the scheduler layer, and the attach can simply be retried until it fails. Once the rings are freed the dangling `q_vector->tx.tx_ring` list is dereferenced on every NAPI poll with no race to win and an unbounded grooming window.
- PR:LPrivileges required, low
- Attaching the XDP program requires only CAP_NET_ADMIN scoped to the network namespace owning the netdev (`netlink_net_capable`), which an unprivileged user holds inside `unshare -Urn`; `ice_xdp()` explicitly accepts subfunction (`ICE_VSI_SF`) VSIs, which are routinely delegated into container namespaces for XDP workloads.
- UI:NUser interaction, none
- The attacker performs the XDP attach and generates the traffic that drives NAPI polling entirely on their own; no action by any other user or administrator is needed.
- S:UScope, unchanged
- The freed `ice_tx_ring` objects and the corrupted state are all kernel-resident within the same security authority; there is no VM, IOMMU, or sandbox boundary crossed.
- C:HConfidentiality impact, high
- The use-after-free lets a groomed slab object supply attacker-controlled `next`, `ring_stats`, `desc`, and `xsk_pool` pointers that the driver dereferences in softirq context, yielding an arbitrary kernel-memory read primitive rather than a bounded leak.
- I:HIntegrity impact, high
- `ice_clean_tx_irq()` and `ice_xmit_zc()` write through the freed ring (`next_to_clean`, `next_to_use`, descriptor memory) and call `dev_kfree_skb_any()` on attacker-supplied `tx_buf` pointers, providing arbitrary-write and arbitrary-free primitives usable for control-flow hijack.
- A:HAvailability impact, high
- The commit documents an immediate general protection fault in `__ice_update_sample()` from softirq/NAPI context, which panics the machine and takes down the network interface for every user of the host.