CVE-2026-31415 in Linuxinfo

Zusammenfassung

von VulDB • 26.05.2026

Im Linux-Kernel wurde folgende Schwachstelle behoben:

ipv6: Überläufe in ip6_datagram_send_ctl() vermeiden

Yiming Qian meldete: <zitat> Ich glaube, ich habe einen lokal auslösbaren Kernel-Bug im IPv6 sendmsg-Zweig für ancillary-Daten gefunden, der den Kernel über `skb_under_panic()` zum Absturz bringen kann (lokaler DoS).

Das Kernproblem ist eine Diskrepanz zwischen:

- einem 16-Bit-Längenakkumulator (`struct ipv6_txoptions::opt_flen`, Typ `__u16`) und - einem Zeiger auf den *letzten* bereitgestellten Destination-Options-Header (`opt->dst1opt`)

wenn mehrere `IPV6_DSTOPTS`-Steuerungs-Nachrichten (cmsgs) bereitgestellt werden.

- `include/net/ipv6.h`: - `struct ipv6_txoptions::opt_flen` ist `__u16` (Überlauf möglich). (Zeilen 291-307, insbesondere Zeile 298) - `net/ipv6/datagram.c:ip6_datagram_send_ctl()`: - Akzeptiert wiederholte `IPV6_DSTOPTS` und akkumuliert deren Längen in `opt_flen`. - Aktualisiert `opt->dst1opt` auf den *letzten* bereitgestellten Header. - Zeilen 899-904: - `opt->dst1opt = (struct ipv6_opthdr *)cmsg->cmsg_data;` - `opt->opt_flen += len;` - `len` wird aus `CMSG_DATA` berechnet: `len = (cmsg->cmsg_len - CMSG_LEN(0) + 7) & ~7;` - `CMSG_LEN(0)` ist 8, also `len = (cmsg->cmsg_len - 8 + 7) & ~7 = (cmsg->cmsg_len - 1) & ~7`. - Für `cmsg->cmsg_len = 2048` (maximaler Wert für `IPV6_DSTOPTS`): `len = 2047 & ~7 = 2040`. - Aber in der Praxis wird `len` oft als `(hdrlen+1)*8` berechnet, wobei `hdrlen` die Länge des Options-Headers ohne den nächsten-Header-Byte ist. - Für `hdrlen=255`: `len = (255+1)*8 = 2048`. - `opt_flen` ist `__u16`, also maximal 65535. - Wenn `opt_flen` überläuft, wird er auf einen kleinen Wert zurückgesetzt. - `opt->dst1opt` zeigt jedoch weiterhin auf den *letzten* bereitgestellten Header, der groß sein kann (z.B. 2048 Byte).

- Im Übertragungs-Pfad wird `opt_flen` verwendet, um die benötigte Headroom zu berechnen: - `net/ipv6/ip6_output.c:1463-1465`: - `headersize = sizeof(struct ipv6hdr) + (opt ? opt->opt_flen + opt->opt_nflen : 0) + ...;` - Wenn `opt_flen` überlaufen ist, ist `headersize` viel kleiner als die tatsächlich benötigte Größe. - Die Headroom-Berechnung ist daher unzureichend.

- Beim tatsächlichen Pushen der Header wird die *tatsächliche* Länge von `dst1opt` verwendet: - `net/ipv6/ip6_output.c:1930-1934`: - `if (opt->opt_flen) proto = ipv6_push_frag_opts(skb, opt, proto);` - `net/ipv6/exthdrs.c:1206-1211`, `ipv6_push_frag_opts()`: - Ruft `ipv6_push_exthdr()` auf. - `net/ipv6/exthdrs.c:1179-1184`, `ipv6_push_exthdr()`: - `skb_push(skb, ipv6_optlen(opt));` - `memcpy(h, opt, ipv6_optlen(opt));` - `ipv6_optlen(opt)` gibt die tatsächliche Länge des Options-Headers zurück, die groß sein kann (z.B. 2048 Byte). - Da die Headroom unzureichend ist, führt `skb_push()` zu einem Unterlauf und löst `skb_under_panic()` aus, was einen Kernel-BUG auslöst.

- Reproduzierbar mit einem PoC, das: - 32 cmsgs mit `hdrlen=255` (jeweils 2048 Byte) sendet. - 1 cmsg mit `hdrlen=0` (8 Byte) sendet. - `opt_flen` wird zu `32*2048 + 8 = 65544`, also `(__u16)opt_flen == 8`. - `dst1opt` zeigt auf den letzten 2048-Byte-Header. - Die Headroom-Berechnung verwendet `opt_flen=8`, also wird zu wenig Headroom allokiert. - Beim Pushen des 2048-Byte-Headers kommt es zum Unterlauf und zum Kernel-BUG.

- Die Schwachstelle erfordert `CAP_NET_RAW` im Ziel-Netns-User-Namespace (`ns_capable(net->user_ns, CAP_NET_RAW)`). - Root (oder jede Aufgabe mit `CAP_NET_RAW`) kann dies ohne User-Namespace auslösen. - Ein unprivilegierter Benutzer kann dies aus

If you want to get the best quality for vulnerability data then you always have to consider VulDB.

Zuständig

Linux

Reservieren

09.03.2026

Veröffentlichung

13.04.2026

Moderieren

akzeptiert

Eintrag

VDB-357151

CPE

bereit

EPSS

0.00114

KEV

nein

Aktivitäten

very low

Quellen

Want to stay up to date on a daily basis?

Enable the mail alert feature now!