CVE-2026-31415: ipv6: avoid overflows in ip6_datagram_send_ctl()

Published Apr 13, 2026
·
Updated

In the Linux kernel, the following vulnerability has been resolved:

ipv6: avoid overflows in ip6datagramsendctl()

Yiming Qian reported : <quote> I believe I found a locally triggerable kernel bug in the IPv6 sendmsg ancillary-data path that can panic the kernel via skbunderpanic() (local DoS).

The core issue is a mismatch between:

- a 16-bit length accumulator (struct ipv6txoptions::optflen, type u16) and - a pointer to the last provided destination-options header (opt->dst1opt)

when multiple IPV6DSTOPTS control messages (cmsgs) are provided.

- include/net/ipv6.h: - struct ipv6txoptions::optflen is u16 (wrap possible). (lines 291-307, especially 298) - net/ipv6/datagram.c:ip6datagramsendctl(): - Accepts repeated IPV6DSTOPTS and accumulates into optflen without rejecting duplicates. (lines 909-933) - net/ipv6/ip6output.c:ip6appenddata(): - Uses opt->optflen + opt->optnflen to compute header sizes/headroom decisions. (lines 1448-1466, especially 1463-1465) - net/ipv6/ip6output.c:ip6makeskb(): - Calls ipv6pushfragopts() if opt->optflen is non-zero. (lines 1930-1934) - net/ipv6/exthdrs.c:ipv6pushfragopts() / ipv6pushexthdr(): - Push size comes from ipv6optlen(opt->dst1opt) (based on the pointed-to header). (lines 1179-1185 and 1206-1211)

1. optflen is a 16-bit accumulator:

- include/net/ipv6.h:298 defines u16 optflen; / after fragment hdr /.

2. ip6datagramsendctl() accepts repeated IPV6DSTOPTS cmsgs and increments optflen each time:

- In net/ipv6/datagram.c:909-933, for IPV6DSTOPTS: - It computes len = ((hdr->hdrlen + 1) << 3); - It checks CAPNETRAW using nscapable(net->userns, CAPNETRAW). (line 922) - Then it does: - opt->optflen += len; (line 927) - opt->dst1opt = hdr; (line 928)

There is no duplicate rejection here (unlike the legacy IPV62292DSTOPTS path which rejects duplicates at net/ipv6/datagram.c:901-904).

If enough large IPV6DSTOPTS cmsgs are provided, optflen wraps while dst1opt still points to a large (2048-byte) destination-options header.

In the attached PoC (poc.c):

- 32 cmsgs with hdrlen=255 => len = (255+1)8 = 2048 - 1 cmsg with hdrlen=0 => len = 8 - Total increment: 322048 + 8 = 65544, so (u16)optflen == 8 - The last cmsg is 2048 bytes, so dst1opt points to a 2048-byte header.

3. The transmit path sizes headers using the wrapped optflen:

- In net/ipv6/ip6output.c:1463-1465: - headersize = sizeof(struct ipv6hdr) + (opt ? opt->optflen + opt->optnflen : 0) + ...;

With wrapped optflen, headersize/headroom decisions underestimate what will be pushed later.

4. When building the final skb, the actual push length comes from dst1opt and is not limited by wrapped optflen:

- In net/ipv6/ip6output.c:1930-1934: - if (opt->optflen) proto = ipv6pushfragopts(skb, opt, proto); - In net/ipv6/exthdrs.c:1206-1211, ipv6pushfragopts() pushes dst1opt via ipv6pushexthdr(). - In net/ipv6/exthdrs.c:1179-1184, ipv6pushexthdr() does: - skbpush(skb, ipv6optlen(opt)); - memcpy(h, opt, ipv6optlen(opt));

With insufficient headroom, skbpush() underflows and triggers skbunderpanic() -> BUG():

- net/core/skbuff.c:2669-2675 (skbpush() calls skbunderpanic()) - net/core/skbuff.c:207-214 (skbpanic() ends in BUG())

- The IPV6DSTOPTS cmsg path requires CAPNETRAW in the target netns user namespace (nscapable(net->userns, CAPNETRAW)). - Root (or any task with CAPNETRAW) can trigger this without user namespaces. - An unprivileged uid=1000 user can trigger this if unprivileged user namespaces are enabled and it can create a userns+netns to obtain namespaced CAPNETRAW (the attached PoC does this).

- Local denial of service: kernel BUG/panic (system crash). - ---truncated---

Affected Software

15 affected components
Linux Linux kernel
Linux Linux kernel>=2.6.14<5.10.253
Linux Linux kernel>=5.11<5.15.203
Linux Linux kernel>=5.16<6.1.168
Linux Linux kernel>=6.2<6.6.134
Linux Linux kernel>=6.7<6.12.81
Linux Linux kernel>=6.13<6.18.22
Linux Linux kernel>=6.19<6.19.12
Linux Linux kernel=7.0-rc1
Linux Linux kernel=7.0-rc2
Linux Linux kernel=7.0-rc3
Linux Linux kernel=7.0-rc4
Linux Linux kernel=7.0-rc5
Linux Linux kernel=7.0-rc6
Linux Linux kernel=7.0-rc7

Event History

Apr 13, 2026
CVE Published
via MITRE·01:21 PM
Data Sourced
via MITRE·01:21 PM
Description
Data Sourced
via NVD·02:16 PM
RemedyDescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-31415?

CVE-2026-31415 is considered a high severity vulnerability due to its potential for local exploitation.

2

How do I fix CVE-2026-31415?

To fix CVE-2026-31415, update to the latest stable version of the Linux kernel that includes the patch.

3

What systems are affected by CVE-2026-31415?

CVE-2026-31415 affects the Linux kernel, particularly systems that implement IPv6 functionality.

4

Can CVE-2026-31415 be exploited remotely?

CVE-2026-31415 is regarded as a locally exploitable vulnerability, requiring the attacker to have local access to the system.

5

What impact does CVE-2026-31415 have on system security?

The impact of CVE-2026-31415 is that it could allow attackers to cause denial of service or execute arbitrary code with elevated privileges.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203