Skip to content

In the Linux kernel, the following vulnerability has been...

Moderate severity Unreviewed Published Apr 13, 2026 to the GitHub Advisory Database • Updated Jul 14, 2026

Package

No package listedSuggest a package

Affected versions

Unknown

Patched versions

Unknown

Description

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

ipv6: avoid overflows in ip6_datagram_send_ctl()

Yiming Qian reported :

I believe I found a locally triggerable kernel bug in the IPv6 sendmsg
ancillary-data path that can panic the kernel via skb_under_panic()
(local DoS).

The core issue is a mismatch between:

  • a 16-bit length accumulator (struct ipv6_txoptions::opt_flen, type
    __u16) and
  • a pointer to the last provided destination-options header (opt->dst1opt)

when multiple IPV6_DSTOPTS control messages (cmsgs) are provided.

  • include/net/ipv6.h:
    • struct ipv6_txoptions::opt_flen is __u16 (wrap possible).
      (lines 291-307, especially 298)
  • net/ipv6/datagram.c:ip6_datagram_send_ctl():
    • Accepts repeated IPV6_DSTOPTS and accumulates into opt_flen
      without rejecting duplicates. (lines 909-933)
  • net/ipv6/ip6_output.c:__ip6_append_data():
    • Uses opt->opt_flen + opt->opt_nflen to compute header
      sizes/headroom decisions. (lines 1448-1466, especially 1463-1465)
  • net/ipv6/ip6_output.c:__ip6_make_skb():
    • Calls ipv6_push_frag_opts() if opt->opt_flen is non-zero.
      (lines 1930-1934)
  • net/ipv6/exthdrs.c:ipv6_push_frag_opts() / ipv6_push_exthdr():
    • Push size comes from ipv6_optlen(opt->dst1opt) (based on the
      pointed-to header). (lines 1179-1185 and 1206-1211)
  1. opt_flen is a 16-bit accumulator:
  • include/net/ipv6.h:298 defines __u16 opt_flen; /* after fragment hdr */.
  1. ip6_datagram_send_ctl() accepts repeated IPV6_DSTOPTS cmsgs
    and increments opt_flen each time:
  • In net/ipv6/datagram.c:909-933, for IPV6_DSTOPTS:
    • It computes len = ((hdr->hdrlen + 1) << 3);
    • It checks CAP_NET_RAW using ns_capable(net->user_ns, CAP_NET_RAW). (line 922)
    • Then it does:
      • opt->opt_flen += len; (line 927)
      • opt->dst1opt = hdr; (line 928)

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

If enough large IPV6_DSTOPTS cmsgs are provided, opt_flen 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: 32*2048 + 8 = 65544, so (__u16)opt_flen == 8
  • The last cmsg is 2048 bytes, so dst1opt points to a 2048-byte header.
  1. The transmit path sizes headers using the wrapped opt_flen:
  • In net/ipv6/ip6_output.c:1463-1465:
    • headersize = sizeof(struct ipv6hdr) + (opt ? opt->opt_flen + opt->opt_nflen : 0) + ...;

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

  1. When building the final skb, the actual push length comes from
    dst1opt and is not limited by wrapped opt_flen:
  • In net/ipv6/ip6_output.c:1930-1934:
    • if (opt->opt_flen) proto = ipv6_push_frag_opts(skb, opt, proto);
  • In net/ipv6/exthdrs.c:1206-1211, ipv6_push_frag_opts() pushes
    dst1opt via ipv6_push_exthdr().
  • In net/ipv6/exthdrs.c:1179-1184, ipv6_push_exthdr() does:
    • skb_push(skb, ipv6_optlen(opt));
    • memcpy(h, opt, ipv6_optlen(opt));

With insufficient headroom, skb_push() underflows and triggers
skb_under_panic() -> BUG():

  • net/core/skbuff.c:2669-2675 (skb_push() calls skb_under_panic())

  • net/core/skbuff.c:207-214 (skb_panic() ends in BUG())

  • The IPV6_DSTOPTS cmsg path requires CAP_NET_RAW in the target
    netns user namespace (ns_capable(net->user_ns, CAP_NET_RAW)).

  • Root (or any task with CAP_NET_RAW) 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 CAP_NET_RAW (the attached PoC does this).

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

---truncated---

References

Published by the National Vulnerability Database Apr 13, 2026
Published to the GitHub Advisory Database Apr 13, 2026
Last updated Jul 14, 2026

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(2nd percentile)

Weaknesses

Reachable Assertion

The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary. Learn more on MITRE.

CVE ID

CVE-2026-31415

GHSA ID

GHSA-2rf4-5672-vqwm

Source code

No known source code

Dependabot alerts are not supported on this advisory because it does not have a package from a supported ecosystem with an affected and fixed version.

Learn more about GitHub language support

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.