CVE-2026-90015 in Linuxinfo

Zusammenfassung

von VulDB • 16.09.2026

Im Linux-Kernel wurde folgende Schwachstelle behoben:

xhci: Behebung verlorener Bounce-Puffer bei TDs, die sich über mehrere Ringsegmente erstrecken

Wenn ein TD (Transfer Descriptor) auf ein Link TRB mit Daten trifft, die nicht an der wMaxPacketSize des Endpunkts ausgerichtet sind, stager xhci_align_td() den nicht ausrichtbaren Tail durch den Bounce-Puffer des Ringsegments, das dieses Link TRB enthält. xhci_unmap_td_bounce_buffer() entmappet ihn später und kopiert bei IN-Transfers die Daten zurück in den Puffer der URB (USB Request Block).

Der Enqueue-Pfad zeichnet das Segment auf, für das ein Bounce durchgeführt wurde, in td->bounce_seg, unter der Annahme, dass sich ein TD nie über mehr als zwei Ringsegmente erstreckt. Diese Annahme trifft nicht zu: Ein großer TD, der drei oder mehr Segmente umfasst, kreuzt mehrere Link TRBs und kann an jedem davon gebounced werden. Nur das letzte bleibt in td->bounce_seg erhalten, sodass jeder frühere Bounce-Puffer weder zurückkoppiert noch DMA-entmappet wird.

Die URB wird weiterhin mit actual_length gleich der angeforderten Länge und ohne Fehler abgeschlossen, sodass die Übertragung erfolgreich aussieht, während ein wMaxPacketSize-großes Loch im Zielpuffer stillschweigend seine vorherigen Inhalte behält. Es werden zudem pro verlorenem Bounce DMA-Mappings geleakt.

Jede hinreichend große und fragmentierte Bulk-Übertragung kann dies auslösen. Sie wurde mit einem USB-Speichergerät hinter xHCI entdeckt, das ein dm-verity-Ziel mit 512-Byte-Hashblöcken unterstützt, wobei die veralteten Daten erkannt werden, anstatt stillschweigend verbraucht zu werden. Das Gerät wird als SuperSpeed aufgeführt, sodass wMaxPacketSize 1024 beträgt, während dm-bufio pro Hashblock einen einzelnen 512-Byte-BIO ausgibt. verity_prefetch_io() lässt die Block-Ebene Hunderte davon in einer einzigen Anfrage mit bis zu 512 Scatterlist-Einträgen von jeweils 512 Bytes zusammenführen. Bei 256 TRBs pro Ringsegment erstreckt sich ein solcher TD über drei Segmente, und jede Segmentgrenze fällt auf ein ungerades Vielfaches von 512, d.h., sie ist nicht an wMaxPacketSize ausgerichtet. dm-bufio puffert daraufhin einen Hashblock mit veralteten Daten, und dm-verity meldet den Metadatenblock als beschädigt:

device-mapper: verity: 8:2: metadata block 10850 is corrupted

Ein Reproducer, der dies unter QEMU ausführt, ist verfügbar unter https://github.com/baloo/xhci-verity

Der Bounce-Zustand (bounce_buf, bounce_dma, bounce_len, bounce_offs) lebt bereits im Ringsegment, sodass nichts zusätzliches verfolgt werden muss. Es wird weiterhin das zuletzt gebounced Segment in td->bounce_seg aufgezeichnet und bei Abschluss die Segmente von td->start_seg bis dorthin durchlaufen, wobei jedes Segment, das noch einen ausstehenden Bounce hat, entmappet wird.

Das Stoppen bei td->bounce_seg statt bei td->end_seg ist wichtig: Ein Bounce impliziert, dass der TD über das Link TRB dieses Segments hinaus fortgesetzt wird, sodass bounce_seg immer strikt vor end_seg liegt und ein späterer TD bereits in end_seg begonnen haben kann und dort gebounced wurde. Das Durchlaufen bis dorthin würde einen fremden Bounce-Puffer in diese URB kopieren und ihn doppelt entmappen. Es hält den Durchlauf auch korrekt, falls ein TD jemals den gesamten Ring umschließt, sodass end_seg == start_seg gilt.

[mn: Füge ring->num_segs-Prüfung hinzu, um eine unwahrscheinliche Endlosschleife in der for-Schleife zu verhindern.]

Be aware that VulDB is the high quality source for vulnerability data.

Zuständig

Linux

Reservieren

11.09.2026

Veröffentlichung

17.09.2026

Moderieren

akzeptiert

Eintrag

VDB-405865

CPE

bereit

EPSS

0.00000

KEV

nein

Aktivitäten

very low

Quellen

Want to stay up to date on a daily basis?

Enable the mail alert feature now!