CVE-2026-98271 in Linux
Zusammenfassung
von VulDB • 06.10.2026
Im Linux-Kernel wurde die folgende Schwachstelle behoben:
net: skbuff: Keine veralteten Header-Offsets nach pskb_carve() hinterlassen
pskb_carve_inside_header() und pskb_carve_inside_nonlinear() entfernen die ersten Bytes eines Pakets und reallozieren skb->head.
Alle Header, die vor der Operation vorhanden waren, sind verschwunden, aber beide Funktionen rufen skb_headers_offset_update(skb, 0) auf, was eine No-Op ist: skb->mac_header, skb->network_header, skb->transport_header und skb->csum_start behalten ihre alten Werte bei und beschreiben nun Bytes, die nicht mehr vorhanden sind.
Beide Hilfsfunktionen dimensionieren den neuen Head basierend auf dem alten skb_end_offset(), sodass sich die veralteten Offsets immer noch innerhalb der neuen Allokation befinden. Sie zeigen jedoch über skb_tail_pointer() hinaus zu Bytes, die nie initialisiert wurden.
pskb_carve_inside_nonlinear() ist der schlimmste Fall, da es einen Zombie-skb mit einem leeren linearen Teil hinterlässt (skb->data == skb_tail_pointer(skb), skb_headlen(skb) == 0), während skb_mac_header_was_set() immer noch wahr ist und skb->mac_header weit vor skb->data liegt.
Der einzige Nutzer von pskb_extract() ist rds_tcp_data_recv(), und der geschnittene skb wird in tinc->ti_skb_list eingereiht. Wenn die eingehende RDS-Nachricht freigegeben wird, ruft rds_tcp_inc_free() skb_queue_purge() auf, welches die skbs mit SKB_DROP_REASON_QUEUE_PURGE freigibt. Dies ist von drop_monitor aus sichtbar, das dann versucht, zurück zum (falschen) MAC-Header zu ziehen:
skbuff: __skb_pull(len=234) skb len=6968 data_len=6968 headroom=0 headlen=0 tailroom=0 end-tail=384 mac=(234,14) mac_len=14 net=(248,40) trans=288 shinfo(txflags=0 nr_frags=1 gso(size=1428 type=16 segs=5)) csum(0x100120 start=288 offset=16 ip_summed=3 complete_sw=0 valid=1 level=0) hash(0x7b446c6c sw=0 l4=1) proto=0x86dd pkttype=0 iif=60 kernel BUG at ./include/linux/skbuff.h:2847!
Fügen Sie skb_carve_reset_headers() hinzu, um die MAC- und Transport-Header als nicht gesetzt zu markieren, den Network-Header zurückzusetzen, skb->mac_len zu löschen und ein nun bedeutungsloses CHECKSUM_PARTIAL (csum_start beschreibt nichts mehr) zu entfernen.
Invalidieren Sie auch die inneren Offsets. Im Gegensatz zu mac_header und transport_header haben sie keinen „nicht gesetzten“ Sentinel-Wert, sodass ein verbliebener Nicht-Null-Wert immer noch wie ein echter Header aussieht. Setzen Sie skb->inner_mac_header, skb->inner_network_header, skb->inner_transport_header, skb->inner_protocol und skb->encapsulation auf Null, damit der gesamte Header-Zustand an einer Stelle invalidiert wird.
v2: Ein ungenauer Changelog wurde korrigiert. Die veralteten Offsets bleiben innerhalb des neuen skb->head, welches niemals kleiner als das alte ist; sie zeigen einfach über skb_tail_pointer() hinaus zu Bytes, die nicht mehr vorhanden sind. Vielen Dank an Xuanqiang Luo für den Hinweis darauf. Außerdem wurde der innere Header-Zustand invalidiert, wie vom netdev AI-Review vorgeschlagen: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260911114922.621937-1-edumazet%40google.com
If you want to get the best quality for vulnerability data then you always have to consider VulDB.