{
  "schemaVersion": 1,
  "attribution": [
    {
      "source": "CISA Known Exploited Vulnerabilities",
      "url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
      "licence": "US government work"
    },
    {
      "source": "GitHub Advisory Database",
      "url": "https://github.com/advisories",
      "licence": "CC BY 4.0"
    },
    {
      "source": "Have I Been Pwned",
      "url": "https://haveibeenpwned.com/",
      "licence": "CC BY 4.0"
    },
    {
      "source": "CVE Program (CVE records)",
      "url": "https://www.cve.org/Legal/TermsOfUse",
      "licence": "CVE Terms of Use",
      "notice": "Copyright © 1999-2026, The MITRE Corporation. CVE is a trademark and the CVE logo is a registered trademark of The MITRE Corporation.",
      "terms": "CVE Usage: MITRE hereby grants you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Common Vulnerabilities and Exposures (CVE™). Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy."
    },
    {
      "source": "FIRST EPSS",
      "url": "https://www.first.org/epss/",
      "licence": "free to use; FIRST requests attribution"
    }
  ],
  "record": {
    "id": "CVE-2026-31415",
    "sourceURL": "https://www.cve.org/CVERecord?id=CVE-2026-31415",
    "idYear": 2026,
    "status": "PUBLISHED",
    "publishedAt": "2026-04-13T13:21:03.284Z",
    "updatedAt": "2026-10-15T01:15:51.840Z",
    "importedAt": "2026-10-24T01:58:02.025Z",
    "snapshot": {
      "id": "cve_2026-10-24_midnight_baseline",
      "at": "2026-10-24T00:00:00.000Z",
      "source": "https://github.com/CVEProject/cvelistV5/releases/tag/cve_2026-10-24_0100Z"
    },
    "facts": {
      "title": "ipv6: avoid overflows in ip6_datagram_send_ctl()",
      "summary": "In the Linux kernel, the following vulnerability has been resolved:\n\nipv6: avoid overflows in ip6_datagram_send_ctl()\n\nYiming Qian reported :\n<quote>\n I believe I found a locally triggerable kernel bug in the IPv6 sendmsg\n ancillary-data path that can panic the kernel via `skb_under_panic()`\n (local DoS).\n\n The core issue is a mismatch between:\n\n - a 16-bit length accumulator (`struct ipv6_txoptions::opt_flen`, type\n `__u16`) and\n - a pointer to the *last* provided destination-options header (`opt->dst1opt`)\n\n when multiple `IPV6_DSTOPTS` control messages (cmsgs) are provided.\n\n - `include/net/ipv6.h`:\n   - `struct ipv6_txoptions::opt_flen` is `__u16` (wrap possible).\n (lines 291-307, especially 298)\n - `net/ipv6/datagram.c:ip6_datagram_send_ctl()`:\n   - Accepts repeated `IPV6_DSTOPTS` and accumulates into `opt_flen`\n without rejecting duplicates. (lines 909-933)\n - `net/ipv6/ip6_output.c:__ip6_append_data()`:\n   - Uses `opt->opt_flen + opt->opt_nflen` to compute header\n sizes/headroom decisions. (lines 1448-1466, especially 1463-1465)\n - `net/ipv6/ip6_output.c:__ip6_make_skb()`:\n   - Calls `ipv6_push_frag_opts()` if `opt->opt_flen` is non-zero.\n (lines 1930-1934)\n - `net/ipv6/exthdrs.c:ipv6_push_frag_opts()` / `ipv6_push_exthdr()`:\n   - Push size comes from `ipv6_optlen(opt->dst1opt)` (based on the\n pointed-to header). (lines 1179-1185 and 1206-1211)\n\n 1. `opt_flen` is a 16-bit accumulator:\n\n - `include/net/ipv6.h:298` defines `__u16 opt_flen; /* after fragment hdr */`.\n\n 2. `ip6_datagram_send_ctl()` accepts *repeated* `IPV6_DSTOPTS` cmsgs\n and increments `opt_flen` each time:\n\n - In `net/ipv6/datagram.c:909-933`, for `IPV6_DSTOPTS`:\n   - It computes `len = ((hdr->hdrlen + 1) << 3);`\n   - It checks `CAP_NET_RAW` using `ns_capable(net->user_ns,\n CAP_NET_RAW)`. (line 922)\n   - Then it does:\n     - `opt->opt_flen += len;` (line 927)\n     - `opt->dst1opt = hdr;` (line 928)\n\n There is no duplicate rejection here (unlike the legacy\n `IPV6_2292DSTOPTS` path which rejects duplicates at\n `net/ipv6/datagram.c:901-904`).\n\n If enough large `IPV6_DSTOPTS` cmsgs are provided, `opt_flen` wraps\n while `dst1opt` still points to a large (2048-byte)\n destination-options header.\n\n In the attached PoC (`poc.c`):\n\n - 32 cmsgs with `hdrlen=255` => `len = (255+1)*8 = 2048`\n - 1 cmsg with `hdrlen=0` => `len = 8`\n - Total increment: `32*2048 + 8 = 65544`, so `(__u16)opt_flen == 8`\n - The last cmsg is 2048 bytes, so `dst1opt` points to a 2048-byte header.\n\n 3. The transmit path sizes headers using the wrapped `opt_flen`:\n\n- In `net/ipv6/ip6_output.c:1463-1465`:\n  - `headersize = sizeof(struct ipv6hdr) + (opt ? opt->opt_flen +\n opt->opt_nflen : 0) + ...;`\n\n With wrapped `opt_flen`, `headersize`/headroom decisions underestimate\n what will be pushed later.\n\n 4. When building the final skb, the actual push length comes from\n `dst1opt` and is not limited by wrapped `opt_flen`:\n\n - In `net/ipv6/ip6_output.c:1930-1934`:\n   - `if (opt->opt_flen) proto = ipv6_push_frag_opts(skb, opt, proto);`\n - In `net/ipv6/exthdrs.c:1206-1211`, `ipv6_push_frag_opts()` pushes\n `dst1opt` via `ipv6_push_exthdr()`.\n - In `net/ipv6/exthdrs.c:1179-1184`, `ipv6_push_exthdr()` does:\n   - `skb_push(skb, ipv6_optlen(opt));`\n   - `memcpy(h, opt, ipv6_optlen(opt));`\n\n With insufficient headroom, `skb_push()` underflows and triggers\n `skb_under_panic()` -> `BUG()`:\n\n - `net/core/skbuff.c:2669-2675` (`skb_push()` calls `skb_under_panic()`)\n - `net/core/skbuff.c:207-214` (`skb_panic()` ends in `BUG()`)\n\n - The `IPV6_DSTOPTS` cmsg path requires `CAP_NET_RAW` in the target\n netns user namespace (`ns_capable(net->user_ns, CAP_NET_RAW)`).\n - Root (or any task with `CAP_NET_RAW`) can trigger this without user\n namespaces.\n - An unprivileged `uid=1000` user can trigger this if unprivileged\n user namespaces are enabled and it can create a userns+netns to obtain\n namespaced `CAP_NET_RAW` (the attached PoC does this).\n\n - Local denial of service: kernel BUG/panic (system crash).\n -\n---truncated---",
      "affected": [
        {
          "vendor": "Linux",
          "product": "Linux",
          "defaultStatus": "unaffected",
          "versions": [
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "2dbfb003bbf3fc0e94f07efefab0ebcf83029a2a"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "4082f9984a694829153115d28c956a3534f52f29"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "0bdaf54d3aaddfe8df29371260fa8d4939b4fd6f"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "5e4ee5dbea134e9257f205e31a96040bed71e83f"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "63fda74885555e6bd1623b5d811feec998740ba4"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "9ed81d692758dfb9471d7799b24bfa7a08224c31"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "872b74900d5daa37067ac676d9001bb929fc6a2a"
            },
            {
              "version": "333fad5364d6b457c8d837f7d05802d2aaf8a961",
              "status": "affected",
              "versionType": "git",
              "lessThan": "4e453375561fc60820e6b9d8ebeb6b3ee177d42e"
            }
          ]
        },
        {
          "vendor": "Linux",
          "product": "Linux",
          "defaultStatus": "affected",
          "versions": [
            {
              "version": "2.6.14",
              "status": "affected"
            },
            {
              "version": "0",
              "status": "unaffected",
              "versionType": "semver",
              "lessThan": "2.6.14"
            },
            {
              "version": "5.10.253",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "5.10.*"
            },
            {
              "version": "5.15.203",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "5.15.*"
            },
            {
              "version": "6.1.168",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.1.*"
            },
            {
              "version": "6.6.134",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.6.*"
            },
            {
              "version": "6.12.81",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.12.*"
            },
            {
              "version": "6.18.22",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.18.*"
            },
            {
              "version": "6.19.12",
              "status": "unaffected",
              "versionType": "semver",
              "lessThanOrEqual": "6.19.*"
            },
            {
              "version": "7.0",
              "status": "unaffected",
              "versionType": "original_commit_for_fix",
              "lessThanOrEqual": "*"
            }
          ]
        }
      ]
    }
  }
}