製品・ソフトウェアに関する情報
LinuxのLinux Kernelにおける到達可能なアサーションに関する脆弱性
Title LinuxのLinux Kernelにおける到達可能なアサーションに関する脆弱性
Summary

Linuxカーネルにおいて、次の脆弱性が修正されました:ipv6のip6_datagram_send_ctl()におけるオーバーフローを回避する問題です。イーミン・チアン氏より報告されました。IPv6のsendmsg補助データパスにてローカルでトリガ可能なカーネルバグが発見されました。これによりskb_under_panic()を介してカーネルパニックが発生し(ローカルDoS)、システムが停止します。根本原因は16ビット長のアキュムレータ(struct ipv6_txoptions::opt_flen、型__u16)と最後の宛先オプションヘッダーを指すポインタ(opt-dst1opt)との不整合にあります。複数のIPV6_DSTOPTS制御メッセージ(cmsg)が渡された際にこの問題が発生します。include/net/ipv6.hにおいてstruct ipv6_txoptions::opt_flenは__u16型であり、ラップの可能性があります(291-307行、特に298行)。net/ipv6/datagram.cのip6_datagram_send_ctl()関数では繰り返されるIPV6_DSTOPTSを受け入れopt_flenを加算しますが、重複は排除されません(909-933行)。net/ipv6/ip6_output.cの__ip6_append_data()関数はopt-opt_flen+opt-opt_nflenでヘッダーサイズやヘッドルームを計算しています(1448-1466行、特に1463-1465行)。__ip6_make_skb()はopt-opt_flenが非ゼロの場合にipv6_push_frag_opts()を呼び出します(1930-1934行)。ipv6_push_frag_opts()やipv6_push_exthdr()はdst1optに基づくipv6_optlen(opt-dst1opt)でプッシュサイズを決定しています(1179-1185行および1206-1211行)。問題点は次の通りです。1. opt_flenは16ビットのアキュムレータであること(include/net/ipv6.hの298行で定義)。2. ip6_datagram_send_ctl()は繰り返しのIPV6_DSTOPTS cmsgを受け入れ、毎回opt_flenを加算していますが、重複排除措置がありません(net/ipv6/datagram.cの909-933行)。大量の大きなIPV6_DSTOPTS cmsgを提供するとopt_flenはラップしますが、dst1optは依然として大きな(2048バイトの)宛先オプションヘッダーを指し続けます。PoC(poc.c)では32個のhdrlen=255のcmsg(長さ2048バイト)と1個のhdrlen=0のcmsg(長さ8バイト)を送り、合計65544バイト加算してopt_flenは16ビットのため8にラップし、一方でdst1optは2048バイトの最後のcmsgを指します。3. 送信パスはラップしたopt_flenに基づきヘッダーサイズを計算するため(net/ipv6/ip6_output.cの1463-1465行)、実際にプッシュされる長さを過小評価します。4. skbを構築するときはdst1optの長さに基づいてプッシュされるため、opt_flenのラップは制限になりません(net/ipv6/ip6_output.cの1930-1934行、net/ipv6/exthdrs.cの1179-1185および1206-1211行)。ヘッドルームが不足してskb_push()がアンダーフローするとskb_under_panic()を引き起こしBUG()となり、それによりカーネルパニックが発生します。IPV6_DSTOPTS cmsg経路は対象のネットワーク名前空間にCAP_NET_RAW権限を要求します。ルートまたはCAP_NET_RAW権限を持つ任意のプロセスがこの脆弱性を発動可能であり、ユーザー名前空間が有効な場合は権限のないuid=1000のユーザでも名前空間CAP_NET_RAWを取得してトリガ可能です。影響はローカルDoSであり、カーネルのBUGパニックやクラッシュを引き起こします。

Possible impacts 当該ソフトウェアが扱う情報について、外部への漏えいは発生しません。 また、当該ソフトウェアが扱う情報について、書き換えは発生しません。 さらに、当該ソフトウェアが完全に停止する可能性があります。 そして、この脆弱性を悪用した攻撃の影響は、他のソフトウェアには及びません。 
Solution

リリース情報、またはパッチ情報が公開されています。参考情報を参照して適切な対策を実施してください。

Publication Date April 13, 2026, midnight
Registration Date May 22, 2026, 10:56 a.m.
Last Update May 22, 2026, 10:56 a.m.
CVSS3.0 : 警告
Score 5.5
Vector CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
Affected System
Linux
Linux Kernel 2.6.14 以上 5.10.253 未満
Linux Kernel 5.11 以上 5.15.203 未満
Linux Kernel 5.16 以上 6.1.168 未満
Linux Kernel 6.13 以上 6.18.22 未満
Linux Kernel 6.19 以上 6.19.12 未満
Linux Kernel 6.2 以上 6.6.134 未満
Linux Kernel 6.7 以上 6.12.81 未満
Linux Kernel 7.0
CVE (情報セキュリティ 共通脆弱性識別子)
CWE (共通脆弱性タイプ一覧)
その他
Change Log
No Changed Details Date of change
1 [2026年05月22日]
  掲載
May 22, 2026, 10:56 a.m.

NVD Vulnerability Information
CVE-2026-31415
Summary

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

ipv6: avoid overflows in ip6_datagram_send_ctl()

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 `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 */`.

2. `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.

3. 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.

4. 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---

Publication Date April 13, 2026, 11:16 p.m.
Registration Date April 15, 2026, 11:38 a.m.
Last Update April 18, 2026, 6:16 p.m.
Related information, measures and tools
Common Vulnerabilities List