CVE-2026-90015 Overview
CVE-2026-90015 is a Linux kernel vulnerability in the xHCI USB host controller driver. The flaw affects xhci_align_td() handling of Transfer Descriptors (TDs) that span three or more ring segments. The driver assumes a TD never crosses more than two ring segments, so td->bounce_seg records only the last bounced segment. Earlier bounce buffers are never copied back to the URB or DMA-unmapped, silently corrupting IN transfer data and leaking DMA mappings.
Critical Impact
Large fragmented bulk USB transfers can silently receive stale data in wMaxPacketSize-sized holes while reporting success, leading to data integrity failures such as dm-verity metadata corruption on USB-backed storage.
Affected Products
- Linux kernel xhci-hcd USB host controller driver
- Systems using SuperSpeed USB devices with wMaxPacketSize of 1024 bytes
- Storage stacks layering dm-verity or dm-bufio over USB mass storage behind xHCI
Discovery Timeline
- 2026-09-16 - CVE-2026-90015 published to NVD
- 2026-09-16 - Last updated in NVD database
Technical Details for CVE-2026-90015
Vulnerability Analysis
The xHCI driver stages unaligned tail data through a per-segment bounce buffer when a TD reaches a link Transfer Request Block (TRB) with data not aligned to the endpoint's wMaxPacketSize. The enqueue path records the bounced segment in td->bounce_seg. On completion, xhci_unmap_td_bounce_buffer() unmaps the buffer and, for IN transfers, copies data back to the URB buffer.
When a TD spans three or more segments, it crosses multiple link TRBs and can be bounced at each one. Only the last bounced segment survives in td->bounce_seg. Every earlier bounce is skipped during completion. The URB completes with actual_length equal to the requested length and no error indication.
Root Cause
The root cause is an incorrect assumption that a single TD never spans more than two ring segments. The bounce tracking state was designed to record only one bounced segment per TD. Sufficiently large and fragmented bulk transfers invalidate this assumption. At 256 TRBs per ring segment, a TD assembled from hundreds of 512-byte scatterlist entries can span three segments, with each segment boundary falling on an odd multiple of 512 bytes.
Attack Vector
The issue triggers on any large fragmented bulk transfer through xHCI. Reproduction was demonstrated with a USB mass storage device backing a dm-verity target with 512-byte hash blocks. The verity_prefetch_io() path causes the block layer to merge hundreds of small bios into a single request with up to 512 scatterlist entries. The resulting TD spans three ring segments and hits the bug on each boundary. Impact is data integrity loss and DMA mapping leaks rather than direct code execution.
See the reproducer repository for a qemu-based test harness.
Detection Methods for CVE-2026-90015
Indicators of Compromise
- Kernel messages reporting dm-verity metadata corruption such as device-mapper: verity: 8:2: metadata block 10850 is corrupted on USB-backed volumes
- Silent data mismatches in files read from USB mass storage without corresponding I/O errors from the block layer
- Growing DMA mapping counts attributable to xhci-hcd without matching unmap events
Detection Strategies
- Correlate dm-verity or filesystem checksum failures with USB device paths and xHCI controller identifiers to isolate transport-layer corruption from media faults
- Instrument xhci_align_td() and xhci_unmap_td_bounce_buffer() with ftrace or kprobes to observe TDs spanning more than two segments
- Monitor /sys/kernel/debug/dma-api where available for unbalanced allocations attributed to the xHCI driver
Monitoring Recommendations
- Forward kernel ring buffer and journald logs to a central analytics tier and alert on device-mapper: verity and xhci_hcd warning patterns
- Track running kernel versions across the fleet against the fixed commits listed in the patch information section
- Baseline USB mass storage error rates per host to surface silent regressions after workload changes
How to Mitigate CVE-2026-90015
Immediate Actions Required
- Apply the upstream xhci fix that walks segments from td->start_seg through td->bounce_seg and unmaps every pending bounce on completion
- Rebuild and redeploy kernels on hosts that use USB mass storage with dm-verity, dm-integrity, or other checksum-verified storage stacks
- Re-verify data integrity on USB-backed volumes that experienced verity errors, as previously read blocks may have contained silent stale data
Patch Information
The fix records the last bounced segment in td->bounce_seg and, on completion, walks segments from td->start_seg up to td->bounce_seg, unmapping each segment that still has a pending bounce. A ring->num_segs check prevents an unlikely infinite loop when a TD wraps the ring. Backports are available across stable branches:
- Linux Kernel Commit 3c9a2b5
- Linux Kernel Commit 43239fc6
- Linux Kernel Commit 7236bbd2
- Linux Kernel Commit a1629dfb
- Linux Kernel Commit c8124b28
- Linux Kernel Commit e04d5304
- Linux Kernel Commit efaab893
- Linux Kernel Commit ff44dfb0
Workarounds
- Limit the maximum I/O size for USB mass storage devices so that assembled TDs cannot exceed two ring segments, reducing the likelihood of triggering the bounce path across multiple link TRBs
- Avoid layering dm-verity, dm-integrity, or similar checksum-verified stacks over USB mass storage on unpatched kernels until the fix is deployed
- Prefer High-Speed enumeration where feasible so wMaxPacketSize is smaller and alignment boundaries change, though this does not fully eliminate the defect
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.