Look up another CVE · open CVE-2026-93201 in the interactive tracker
CVE-2026-93201
dm-pcache: validate seg_id fields from persistent memory
Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem drivers/md. Debian urgency: unimportant.
What to do, per Debian release
Debian's own status for CVE-2026-93201 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 | not affected | 6.1.190-1 | Nothing to do. bookworm never shipped the vulnerable code. |
| Debian 13trixie | not affected | 6.12.113-1 | Nothing to do. trixie never shipped the vulnerable code. |
| Debian 14forky | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
| Debian unstablesid | fixed | 7.2.6-1 | Update the kernel and reboot. Fixed in 7.2.6-1. A running kernel keeps the old code until the machine restarts. |
The vulnerability
What the bug is
cache_pos_decode(), cache_key_decode() and the last-kset branches of cache_replay(), the writeback worker and the GC worker take a cache segment id from the cache device metadata and index cache->segments[] with it without checking it against cache->n_segs. That metadata is only CRC-protected with a fixed public seed, so whoever supplies the cache device on a table load (CAP_SYS_ADMIN) controls the id; an out-of-range value forms a wild pcache_cache_segment pointer that is dereferenced and written through -- an out-of-bounds read and write driven by on-disk data. Add cache_seg_id_valid() and reject an out-of-range id at each decode site, failing the operation with -EIO instead of indexing past the array. Bound the id against the initialized-segment count (cache_info.n_segs) rather than the physical device total. A forged cache_info.n_segs below seg_num otherwise leaves segments[cache_info.n_segs..seg_num) as zeroed structs whose data pointer is NULL, so a forged id in that window would still be dereferenced. A later patch guarantees cache_info.n_segs <= seg_num, and a driver-created cache sets the two equal, so valid images are unaffected.
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/md/dm-pcache/cache.c
drivers/md/dm-pcache/cache.h
drivers/md/dm-pcache/cache_gc.c
drivers/md/dm-pcache/cache_key.c
drivers/md/dm-pcache/cache_writeback.c
- What this is
- DEVICE-MAPPER PCACHE TARGETMAINTAINERS section matched on drivers/md/dm-pcache/ · dm-devel@lists.linux.dev · Maintained
Check it on the machine
grep -wE 'CONFIG_DM_PCACHE|CONFIG_MD' /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.
Show whether Debian builds this, per release
Debian does not build this code in 2 releases. The build rule could not be established for 2 releases, so nothing is claimed about those.
- bookworm, trixie?
- forky, sidn
- ?
- not established - no Makefile entry for the affected file
- n
- not enabled on any flavour - this release does not build the code
Where a release above reads "not established", no build rule for the affected file was found in that release's kernel tree. That is a gap in this lookup, not a finding that the code is absent.
- Build switches
- CONFIG_DM_PCACHE, CONFIG_MD
- 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-09-17 (31 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.17%, higher than 6.3% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- unimportantsource
- Subsystem
- drivers/md
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 6.18 | 6.18.57 | 96d4b275281b |
| 6.18 | 7.2.6 | b4bf8af5e7d7 |
| 6.18 | 7.3 | 90c990a68460 |
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
- Attacker-controlled cache_seg_id/next_cache_seg_id bytes are consumed only on a local DM_TABLE_LOAD of a pcache target (ctl_ioctl → table_load → dm_pcache_ctr → pcache_cache_start → cache_pos_decode/cache_key_decode/cache_replay) from a supplied DAX cache device; no network, Bluetooth, or USB receive path parses those on-media ids.
- AC:LAttack complexity, low
- The attacker forges pos_onmedia.cache_seg_id, key_onmedia.cache_seg_id and last-kset next_cache_seg_id with a valid CRC because PCACHE_CRC_SEED (0x3B15A) is public, so a crafted INIT_DONE image makes cache_pos_decode/cache_key_decode/cache_replay index cache->segments[] out of bounds on every table load with no race.
- PR:LPrivileges required, low
- ctl_ioctl in dm-ioctl.c gates DM_TABLE_LOAD with capable(CAP_SYS_ADMIN); kernel-CNA scoring of dm-pcache table-load bugs treats that delegated capability (privileged containers, LVM/storage helpers that already hold mapper and DAX/pmem nodes) as Low rather than exclusive init-namespace root.
- UI:NUser interaction, none
- The attacker writes the forged cache_seg_id fields onto their DAX cache device and issues DM_TABLE_LOAD for the pcache target themselves; no separate victim must mount media, open a file, or otherwise interact.
- S:UScope, unchanged
- The wild pcache_cache_segment taken as &cache->segments[id] and the resulting kvalloc/DAX-mapping corruption stay inside the host kernel that loaded the table; this is not a VM escape, IOMMU bypass, or other cross-authority boundary.
- C:HConfidentiality impact, high
- An out-of-range id makes cache_pos_decode, cache_key_decode and cache_replay's last-kset branch take &cache->segments[id] past the kvalloc'd array; cache_pos_addr() then copy_mc_to_kernel of a kset, and cache_key_data_crc() crc32c of key->len bytes, read through the fake object's segment.data — an unbounded kernel over-read.
- I:HIntegrity impact, high
- last_kset_gc/last_kset_writeback store the wild segment pointer into key_tail/dirty_tail; cache_replay then __set_bit()s cache_seg_id from that OOB object into cache->seg_map, and cache_seg_get/cache_seg_put → cache_seg_ctrl_write memcpy_flushcache through the fake cache_seg_ctrl pointer, an out-of-bounds kernel write.
- A:HAvailability impact, high
- Indexing past cache->segments[], or a forged id in [cache_info.n_segs, seg_num) whose kvzalloc'd slot has segment.data NULL, makes cache_pos_addr() and later copy_mc_to_kernel/memcpy_flushcache walk a NULL or unmapped kernel VA during table load or in the GC/writeback workers, oopsing or panicking the host.