2026年7月20日、Linuxカーネルの権限昇格脆弱性「Fraggap」(CVE-2026-53362)の技術詳細が、発見者による解説(writeup)として公開された。IPv6のUDP処理という、普段は誰も意識しない経路のわずかな計算違いから、skb_shared_info への最大15バイトの領域外書き込み(OOB write)が起き、そこを足がかりに非特権ユーザーがroot権限を奪取する。Red Hatはこれを「IPv6 Fragmentation Container Escape」と呼び、コンテナの内側からホストへ抜ける攻撃としても整理している。日本語では、Linuxカーネルの権限昇格ニュース自体は多く報じられる一方で、この Fraggap のカーネル内部で何が起きているかを噛み砕いた解説はまだ見当たらない。この記事は、一次ソースの値を正確に転記しつつ、仕組みの理解と自分の環境の判定に振り切る。攻撃の再現手順やエクスプロイトコードは扱わない。

Fraggapのroot昇格チェーンの概念図。UDPv6のcorking処理でfraggapの会計が食い違い、MSG_SPLICE_PAGESが負のコピー検査を飛ばすことでskb_shared_infoに最大15バイトのOOB書き込みが起き、nr_fragsが0から1へ反転して残存ページが解放され、そのページをPTEページとして再確保してcore_patternを書き換えroot昇格に至る流れ
Fraggap(CVE-2026-53362)のroot昇格チェーンの概念図。具体的な数値・オフセットは意図的に省いた、防御・理解のための俯瞰図

30秒でわかるポイント

これはローカル権限昇格(LPE)。ネットワーク越しの未認証RCEではない。攻撃者はまず対象上でコードを実行できる非特権ユーザーである必要がある(CVSSベクタも AV:L)
根っこは「会計の食い違い」。IPv6のUDP corking経路で fraggap(フラグメント境界を跨ぐ端数バイト)の数え方が経路によってズレ、確保が足りないバッファへ書き込んでしまう
最後の安全弁を MSG_SPLICE_PAGES が外す。本来はエラーで止まるはずの負値チェックが、このフラグ指定時にスキップされ、skb_shared_info へ最大15バイトの OOB write が成立する
前提は CONFIG_IPV6=y。実証された経路はIPv6を使う。IPv4側は別CVE(CVE-2026-53366)として別コミットで修正されている
コンテナエスケープになりうる。Red Hat は SELinux を回避してコンテナからホストのrootへ抜けられると整理。緩和には非特権ユーザー名前空間の無効化があるが副作用がある。恒久対策はカーネル更新と再起動

なお、OSやミドルウェアの脆弱性対応を、CVE分析から防御の型まで体系的に押さえておきたい運用者は、サプライチェーンセキュリティ2026|攻撃手法・防御ツール・実践チェックリストも合わせて読んでほしい。本記事はそのうち「Linuxカーネルの個別CVEに対して、自分の環境がどう該当するかを判定する」実務編にあたる。

Fraggapの時系列(Timeline)

まず、いつ何が起きたのかを一次ソースに沿って並べる。バグの混入から公表まで4年近い時間が経っている点と、修正のメインライン取り込みから公開エクスプロイトまでが1か月弱だった点が、この時系列の要点だ。

日付 出来事
2022-07-12 バグが混入(コミット 773ba4fe9104)。この時点でIPv6/IPv4のcorking経路に会計の食い違いが入る
2023-08-02 MSG_SPLICE_PAGES 経由でこの破壊が到達可能になる(コミット ce650a166335
2026-05-15 発見者が [email protected] へ非公開で報告
2026-06-25 修正がLinuxメインラインへマージ(IPv6側の修正コミットは 736b380e28d0
2026-07-04 CVE-2026-53362(IPv6側)が公表
2026-07-14 Openwall の linux-distros メーリングリストへ通知
2026-07-16 CVE-2026-53366(IPv4側)が公表
2026-07-20 発見者による技術詳細(writeup)とエクスプロイトコードが公開

この並びから読み取るべきことは2つある。

1つは、混入が2022年7月という点だ。バグそのものは長期間カーネルに潜んでいた。ただし「非特権ユーザーが握れる破壊」として実際に到達可能になったのは、MSG_SPLICE_PAGES を経由できるようになった2023年8月以降である。したがって「自分のカーネルが対象か」は単純なリリース時期だけでは決まらず、ディストリのバックポート状況で前後する。ここは後半の確認手順で具体的に潰す。

もう1つは、修正公開から公開エクスプロイトまでの短さだ。メインラインへの修正マージ(6月25日)から、writeupとエクスプロイトの公開(7月20日)まで1か月弱しかない。オープンソースのカーネルでは、修正コミットそのものが「どこが悪かったか」を教えてしまう。修正前後のコードの差分を読めば、変わった箇所は誰にでも分かる。つまり、修正が公開された瞬間から、それを解析して攻撃に転用する動きが始まる。「詳細が出ていないから当分は安全」という判断は、カーネルの脆弱性では特に成り立たない。

発見者クレジット

この脆弱性は、研究者 @_qwerty_po(@physicube)による発見・解析で、writeupも同氏が公開している。IPv4側の悪用可能性の確認については、writeup内で CIQ の Sultan Alsawaf 氏への謝辞が記されている。エクスプロイトは Google の kernelCTF(カーネルの実効的なエクスプロイトを競う場)で使用された。kernelCTF で通用したという事実は、この手法が机上の空論ではなく、現実の環境で安定して権限昇格に使えるレベルに達していることを意味する。

Fraggapで何が起きたのか(技術的要点)

ここからが本題だ。まず、この脆弱性の性質を一段抽象化して言うと、「同じデータを、2つの計算経路が違う長さだと思い込んだ」問題である。片方は「このデータは○バイトある」と数え、もう片方は「○バイトぶんの入れ物を用意する」段でその端数を数え落とす。結果、入れ物が数バイト足りないまま書き込みが走り、隣の重要な構造体を壊す

順番に見ていく。

fraggap とは何か

IPは、送るデータが経路の最大転送単位(MTU)より大きいとき、データをフラグメント(断片)に分割して送る。Linuxカーネルは効率のため、この送信パケットをcorkingという仕組みで少しずつ組み立てる。UDP_CORKMSG_MORE を使うと、複数回の sendmsg() で渡したデータを一旦カーネル内にため込み、最後にまとめて1つ(または複数)のパケットとして送出する。

フラグメントには、各断片のデータ長は8バイト境界に揃えるという決まりがある(先頭以外の断片について)。そのため、断片の切れ目でデータをきれいに割り切れないと、端数のバイトが生じる。この端数を次の断片の先頭へ持ち越す必要があり、この持ち越し分が fraggap(フラグメント境界を跨ぐ端数)である。Fraggapという通称はここから来ている。fraggap 自体は正常動作の一部で、それ自体が悪いわけではない。問題は、この端数バイトの数え方が経路によって食い違っていたことにある。

なぜ最大15バイトはみ出すのか(会計の食い違い)

問題の関数は、IPv6側では __ip6_append_data() だ。ここで新しい skb(ソケットバッファ=カーネルが1パケットを組み立てるための構造体)を確保するとき、コードは大きく次の2つを計算する。

datalen:このskbにコピーすべきデータの長さ。ここには fraggap(持ち越しの端数)がデータとして数え込まれている
alloclen / pagedlen:実際に確保する線形バッファの大きさと、ページ側に回す長さ

脆弱なコードの取り違えは、この2段目にある。writeupの表現を借りれば、コードは fraggap を線形データ領域から外し、pagedlen(ページ側)に付け替えてしまう。すると、線形バッファの確保量が fraggap のぶんだけ小さくなる。数え込んだ長さ(datalen)と、用意した入れ物(alloclen)の間に、ちょうど fraggap ぶんの差が空く。

fraggapの会計の食い違いを示す概念図。datalenは端数バイト(fraggap)をデータとして数え込む一方、線形バッファの確保量alloclenはfraggap分を差し引いてしまい、確保が端数バイトぶん足りなくなる。本来はcopyが負になってエラーで止まるはずが、MSG_SPLICE_PAGES指定時にその検査がスキップされ、確保不足のバッファのすぐ後ろにあるskb_shared_infoへ書き込みがはみ出す
会計の食い違いの概念図。数え込んだ長さ(datalen)と確保量(alloclen)の差が、そのままはみ出し量になる

このズレは最大で15バイトに達する。線形バッファのすぐ後ろには、skb_shared_info という構造体が置かれている。これはこのskbに紐づく「ページ断片の情報」を保持する重要な管理領域で、その先頭付近にはページ断片の個数を示す nr_frags、そしてページ断片の配列 frags[] がある。確保不足のバッファへ端数バイトを書き込むと、その書き込みがskb_shared_info の先頭領域へはみ出し、最大15バイトを上書きする。ここが、この脆弱性の「壊れる場所」だ。

MSG_SPLICE_PAGES が最後の安全弁を外す

ここで当然の疑問が湧く。「確保量とコピー量が食い違うなら、普通はどこかで弾かれるのでは?」——その通りで、本来は弾かれる。カーネルには、コピーすべき残量を計算して、それが負になったらエラーで処理を止める検査がある。会計がズレて残量が負になれば、この検査に引っかかって OOB write は起きないはずだった。

その最後の安全弁を外すのが、MSG_SPLICE_PAGES フラグだ。このフラグは、ユーザー空間のページを(コピーせずに)ゼロコピーでカーネルへ渡すための仕組みで、sendmsg() に指定できる。このフラグが立っていると、先の負値チェックがスキップされる。結果として、確保不足のバッファがそのまま使われ、skb_put()(バッファへの書き込み位置を進める操作)が skb_shared_info の領域まで書き込みを進めてしまう。

つまり、Fraggap の成立条件は概念的には次の重なりだ。(1) corking で fraggap が生じるようにデータを積む、(2) ページ側確保の経路(NETIF_F_SG やページ割り当てが選ばれる条件)を通す、(3) MSG_SPLICE_PAGES で負値チェックを飛ばす。この3つが揃うと、非特権ユーザーが自分のUDPv6ソケットへの sendmsg() だけで、カーネル内の skb_shared_info を狙って壊せる。特別な権限も、外部からの通信も要らない。ローカルで、自分のソケットに対して、である。

なぜ「読者が試せる手順」を載せないか:この記事は、防御と理解のために「なぜ壊れるか」までを書く。一方で、fraggap を生じさせる具体的なバイト数、skb_shared_info 内の正確なオフセット、メモリを狙い通りに配置する手順などは意図的に省いている。それらは攻撃を再現するための情報であり、防御側が自分の環境を判定するのに必要ではないからだ。判定に必要なのは「自分のカーネルが修正済みか」「CONFIG_IPV6 が有効か」であって、それは後半の確認手順で足りる。

OOB書き込みがどうやってroot昇格になるのか(概念)

skb_shared_info を15バイト壊せる、というだけでは、まだ「クラッシュさせられる(DoS)」に近い。これが安定したroot昇格にまで化けるのが、この脆弱性の怖いところだ。writeupが示した流れを、値や手順を省いて概念だけでたどる。

flowchart TD A["OOB write で
skb_shared_info を上書き"] --> B["nr_frags を 0 → 1 へ反転"] B --> C["frags[0] に残っていた
古いページ参照を
『所有している』と誤認"] C --> D["skb 解放時に put_page()
本来所有していないページを解放"] D --> E["宙に浮いた
ダングリングページ発生"] E --> F["解放ページを
PTE(ページテーブル)として再確保
= Dirty Pagetable"] F --> G["物理メモリの
任意読み書きを獲得"] G --> H["core_pattern を上書きし
クラッシュ時にroot権限で
ヘルパーを実行"] H --> I["root 奪取"] style A fill:#7f1d1d,color:#fff style I fill:#7f1d1d,color:#fff style F fill:#78350f,color:#fff style G fill:#78350f,color:#fff

順に言葉にすると、こうなる。

1. nr_frags を 0→1 に反転させる。 skb_shared_info の先頭付近には、ページ断片の個数 nr_frags がある。OOB write でここを 0 から 1 に書き換えると、カーネルは「このskbにはページ断片が1つある」と信じ込む。

2. 残存していた参照を「所有物」に化けさせる。 nr_frags == 0 の間、frags[] 配列の中身はカーネルから無視される。攻撃者はあらかじめ、frags[0] に相当する位置へ、以前の splice 操作で使われたパイプページの参照が残っているように場を整えておく。nr_frags が 1 になった瞬間、カーネルはこの残存参照を「自分が正当に確保したページ断片」として扱い始める。

3. 二重解放でページを宙に浮かせる。 skb が破棄される(ソケットを閉じる等)と、カーネルは frags[] の各ページに対して put_page() を呼び、参照を手放す。ところが frags[0] のページは、このskbが本当は確保していないページだ。結果として、まだ他所から使われているページの参照が1つ余計に落ち、そのページが解放されてしまう。ダングリング(宙吊り)ページの出来上がりだ。

4. 解放ページをページテーブルとして再確保する(Dirty Pagetable)。 解放された物理ページは、カーネルが別用途に再利用する。攻撃者はこれをページテーブル(PTE)ページとして引き当てさせる。攻撃者側にはまだこのページへの参照(マッピング)が残っているため、ページテーブルの中身=どの仮想アドレスがどの物理ページを指すか、を直接書き換えられる状態になる。これが「Dirty Pagetable」と呼ばれる、近年のカーネル攻撃で確立した強力な手筋だ。

5. 物理メモリの任意読み書きから core_pattern を上書きする。 ページテーブルを操作できると、実質的に物理メモリのどこでも読み書きできる。あとは core_pattern(プロセスがクラッシュしたときに実行されるヘルパープログラムを指定するカーネル設定)を、攻撃者が用意したプログラムを指すように書き換え、意図的にクラッシュを起こす。ヘルパーはroot権限で実行されるため、ここで権限昇格が完了する。

この5段の要点は、「たった15バイトの上書き」から「物理メモリ全体の支配」へ、ページテーブルを踏み台にして一気に跳ぶところにある。カーネルの権限昇格が、単一のメモリ破壊から安定した root 奪取へつながるのは、こうした確立した中間手筋(Dirty Pagetable)が存在するからだ。逆に言えば、skb_shared_info を1バイトでも意図せず壊せる欠陥は、それ自体で致命的になりうる、ということでもある。

これはリモートRCEではない — ローカル権限昇格とコンテナエスケープ

深刻度を誤解しないために、この脆弱性の性質を正確に押さえておきたい。見出しの脅威度と、実際にどんなリスクかは分けて考える必要がある。

攻撃元はローカル

Fraggap はローカル権限昇格(LPE)である。攻撃者はまず、対象マシン上でコードを実行できる状態、すなわちローカルの非特権ユーザーになっている必要がある。CVSSベクタもこれを裏づけていて、複数の脆弱性データベースは CVSS 7.8(AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) を割り当てている。先頭の AV:L は「攻撃元区分=ローカル」PR:L は「必要な権限=低(一般ユーザー)」を意味する。ネットワーク越しに、未認証で、いきなり任意コード実行——という類の脆弱性ではない。

ただし「ローカルだから軽い」と読むのは誤りだ。次のような環境では、この LPE こそが最後の砦を破る一手になる。

共用サーバ/マルチテナントホスト:多数の一般ユーザーが同居する環境で、そのうち1人がroot(=全ユーザーのデータ)を奪える
コンテナ/サンドボックス:意図的に権限を絞って動かしているワークロードが、その隔離を破ってホストを奪える
多段攻撃の後半:Webアプリの脆弱性などで一般ユーザーとして侵入した攻撃者が、そこからrootへ昇格する「次の一歩」に使える

Red Hat は「コンテナエスケープ」として整理

とりわけ重要なのが、コンテナからの脱出だ。Red Hat はこの脆弱性を 「IPv6 Fragmentation Container Escape」(RHSB-2026-009、内部通称 ipv6_frag_escape として整理し、深刻度を Important と評価している。Red Hat のアドバイザリは、影響をこう表現している(要旨)。

コンテナ内部にローカルアクセスを持つユーザーが、ホストへ脱出し、SELinux の強制を回避して、システム管理者(root)権限を取得しうる。

なぜコンテナの中から成立するのか。攻撃に必要な部品は UDPv6ソケット・pipe・splice だが、これらは非特権ユーザー名前空間(unprivileged user namespaces)を使えるコンテナの内側からでも用意できる。そして、いったんカーネルの読み書きを握ってしまえば、それは SELinux の強制よりも下のレイヤーだ。SELinux はカーネルの上で動くアクセス制御であり、カーネル自体を書き換えられる攻撃者の前では機能しない。だから「コンテナで隔離しているから安全」「SELinux enforcing だから安全」という前提が、この脆弱性では崩れる。

Fraggapが越える権限境界の概念図。非特権ユーザーまたはコンテナ内のプロセスが、UDPv6ソケットとsplice/pipeを使ってカーネルの任意読み書きを獲得し、SELinuxの強制を回避してホストのroot権限に到達する様子。ローカルアクセスが前提でネットワーク越しではない点を示す
Fraggapが越える境界。非特権プロセスやコンテナが、カーネルR/Wを介してSELinuxを飛び越えホストrootへ達する

IPv6側とIPv4側は別CVE

もう1点、混同しやすいので整理しておく。実証された経路(kernelCTFで使われたもの)はIPv6側で、これが CVE-2026-53362__ip6_append_data()、修正コミット 736b380e28d0)だ。一方、同じ会計ミスはIPv4側にも存在し、こちらは CVE-2026-53366 として、別のコミット(eca856950f7cで修正されている。両者はいずれも「fraggap をページ確保経路で数え落とす」という同系のバグで、CNA(kernel.org)は双方に CVSS 7.8 を割り当てている。

この区別が効いてくるのは「対策」の段だ。IPv6を無効化しても、IPv4側の欠陥は消えない。実証済みの経路を塞ぐ緩和にはなるが、根っこは残る——この点は後述する。

影響範囲:どのカーネルが対象か

「自分は対象か」を判断するための材料を、確定している事実だけで整理する。

観点 内容
対象サブシステム IPv6のUDP corking経路(__ip6_append_data)=CVE-2026-53362。IPv4側の同一バグは CVE-2026-53366
ビルド条件 CONFIG_IPV6=y が前提(IPv6側の実証経路)。多くのディストリは既定で有効
必要な権限 ローカルの非特権ユーザー(コンテナ内・非特権ユーザー名前空間経由を含む)
バグの混入 2022-07-12(773ba4fe9104)。それ以前のカーネルには当該コードが無い
到達可能になった時期 2023-08-02(ce650a166335)で MSG_SPLICE_PAGES 経由が成立
修正(IPv6) 736b380e28d0、2026-06-25 にメインラインへマージ
修正(IPv4) eca856950f7c(同系バグの修正)
深刻度 CVSS 7.8 / High(CNA)。Red Hat は Important、コンテナエスケープとして整理

実務上の注意は、「メインラインの日付」と「自分のディストリのカーネル」は別物という点だ。ディストリ各社は、独自にサポートするカーネルへ修正をバックポートする。したがって、uname -r が古い番号でも修正が入っている(逆に、新しめでもまだ入っていない)ことがある。最終判断は、次章のディストリ別確認で行う。

なお、混入が2022年7月である以上、おおよそその頃以降のメインライン系カーネルが潜在的な対象になるが、実際に非特権から到達可能なのは MSG_SPLICE_PAGES 経由が成立した2023年8月以降だ。正確な該当・非該当は「リリース番号」ではなく「修正がバックポートされているか」で判定するのが確実で、そのための手順を次に示す。

自分のシステムが該当するか(確認手順)

ここからは読み取り専用の確認だ。攻撃を含まない。自分が管理するホストに対してのみ実行してほしい。

flowchart TD S["確認スタート"] --> A["uname -r で
稼働カーネルを確認"] A --> B{"CONFIG_IPV6 は
有効か"} B -- "無効 (is not set)" --> N["IPv6側(53362)の
実証経路は非該当
※IPv4側は別途更新"] B -- "有効 (=y) / 大半はこちら" --> C{"ディストリの修正が
入っているか"} C -- "入っている" --> OK["対応済み
(稼働カーネルを実測で確認)"] C -- "入っていない / 不明" --> D["カーネル更新 → 再起動
までは影響下"] D --> E["更新できるまでは
緩和を検討(本文『対策』)"] style N fill:#14532d,color:#fff style OK fill:#14532d,color:#fff style D fill:#7f1d1d,color:#fff

手順1:稼働カーネルのバージョンを確認する

uname -r

この番号を控えておく。以降のディストリ別確認で使う。パッケージ上のカーネルと、実際に動いているカーネルがずれていることは珍しくない(更新後に再起動していない場合など)。判定は必ず稼働中の番号で行う。

手順2:CONFIG_IPV6 が有効かを確認する

これは Fraggap 特有の切り分けで、価値が高い。CONFIG_IPV6 が無効なら、実証されたIPv6経路(CVE-2026-53362)は成立しないからだ。

# /proc/config.gz がある環境(Arch等)
zcat /proc/config.gz | grep CONFIG_IPV6

# 無い環境(Debian/Ubuntu/RHEL系の多く)
grep CONFIG_IPV6 /boot/config-$(uname -r)

出力の読み方は次の通り。

CONFIG_IPV6=y:IPv6がカーネルに組み込まれている。大半のディストリはこれ。IPv6側の経路が成立しうる
CONFIG_IPV6=m:モジュールとして提供。ロードされていれば同様に成立しうる
# CONFIG_IPV6 is not set:IPv6がビルドされていない。IPv6側(53362)の実証経路は非該当

「IPv6をsysctlで無効化している」と「CONFIG_IPV6が無効」は別物net.ipv6.conf.all.disable_ipv6=1 のような実行時の無効化は、インターフェースでのIPv6通信を止めるだけで、カーネル内のIPv6コード自体は組み込まれたまま残ることが多い。この脆弱性が使うのはローカルのソケット処理経路なので、実行時の disable_ipv6 では塞ぎきれない可能性がある。確実に「非該当」と言えるのは、上のコマンドで # CONFIG_IPV6 is not set が出る場合だ。

手順3:ディストリの修正が取り込まれているか確認する

最終判断はこれで行う。ディストリごとに、修正が自分のカーネルに入っているかを確認する。

Debian / Ubuntu 系:

# インストール済みカーネルの変更履歴からCVE参照を探す
apt-get changelog linux-image-$(uname -r) 2>/dev/null | grep -iE "53362|53366|fraggap|ip6_append"

RHEL / Rocky / AlmaLinux 系:

rpm -q --changelog kernel | grep -iE "53362|53366|fraggap"

変更履歴にCVE番号が現れれば、その修正が取り込まれたビルドである可能性が高い。ただし変更履歴の記法はディストリやパッケージにより差があるため、出なかった=未修正と即断せず、各社のセキュリティトラッカーで最終確認するのが確実だ。

・Ubuntu:https://ubuntu.com/security/CVE-2026-53362(および CVE-2026-53366)で、リリース別の Fixed / Not affected を確認
・Red Hat:RHSB-2026-009ipv6_frag_escape)で対象製品と修正状況を確認
・その他:ディストリのCVEトラッカーで CVE-2026-53362 / CVE-2026-53366 を引く

手順4:コンテナ経由の攻撃面を確認する

コンテナホストでは、非特権ユーザー名前空間が使えるかが攻撃面の広さに直結する。

# 非特権ユーザー名前空間の可否(ディストリで名前が異なる)
sysctl kernel.unprivileged_userns_clone 2>/dev/null
sysctl user.max_user_namespaces

kernel.unprivileged_userns_clone1、あるいは user.max_user_namespaces0 より大きければ、非特権ユーザーがユーザー名前空間を作れる。これは rootless コンテナ等に必要な設定である一方、今回のようなカーネルLPEの攻撃面を広げる要素でもある。値の意味と、無効化の是非(副作用)は次章で扱う。

対策

優先度順に整理する。恒久対策はカーネルの更新と再起動で、これに勝る手はない。

最優先:カーネルを更新して再起動する

# Debian / Ubuntu
sudo apt-get update && sudo apt-get install --only-upgrade linux-image-generic

# RHEL / Rocky / AlmaLinux
sudo dnf update kernel

更新は再起動(またはライブパッチの適用)で初めて有効になる。 パッケージを入れただけでは、稼働中のカーネルは古いままだ。更新後は再起動し、実測で確認する。

# 再起動後、稼働カーネルが更新されているか
uname -r

kpatch / klp(KernelCare、Ubuntu Livepatch、Red Hat のライブパッチ等)を契約している環境では、再起動なしで当てられる場合がある。提供状況は各サービスで確認してほしい。

すぐに再起動できない場合の緩和(いずれも一時しのぎ)

再起動の段取りが取れない場合の緩和策を挙げる。どれも恒久対策ではなく、更新までの時間稼ぎであることを最初に強調しておく。

(A) 非特権ユーザー名前空間を無効化する(コンテナ経由の攻撃面を削る)。 Red Hat が案内している緩和策で、コンテナ内の非特権ユーザーからの経路を塞ぐ。

# 一時的に無効化(再起動で戻る)
sudo sysctl -w user.max_user_namespaces=0

ただし副作用がある。Red Hat も明記している通り、この設定は rootless Podman やアプリケーションのサンドボックスを壊す。非特権ユーザー名前空間に依存するワークロードがある環境では、いきなり適用すると別の障害を招く。適用前に、自分の環境がこの機能に依存していないかを必ず確認すること。

(B) IPv6側の経路を塞ぐ(限定的)。 実証されたのはIPv6経路なので、CONFIG_IPV6を使わない運用が可能な特殊な環境では攻撃面が縮む。ただし次の2点で限定的だ。第一に、前述の通りIPv4側(CVE-2026-53366)は別途残るため、これは「根っこを消す」対策にはならない。第二に、多くの実環境ではIPv6を止めるとサービスに影響が出る。IPv6無効化は更新の代替にはならない、と理解してほしい。

(C) splice() の制限は勧められない。 「そもそも splice を使えなくすればいいのでは」と考えたくなるが、writeup自身がこれを「良い選択肢ではない」と述べているsplice() は多くの正当なプログラムが日常的に使うシステムコールで、seccomp等で一律に塞ぐと広範な機能破壊を招く。緩和策として現実的ではない。

更新後に確認すること(共用ホストの場合)

Fraggap は公開エクスプロイトが存在し、kernelCTFでも通用した実効性のある手法だ。多数の非特権ユーザーが同居する共用ホストでは、「更新したから終わり」で済ませず、更新前に悪用の痕跡がなかったかも検討する価値がある。

ただし率直に書くと、カーネルLPEは、権限昇格に成功したあとで痕跡を消しやすく、Webアプリ侵害のような分かりやすいIoC(侵害指標)が残りにくい。公的機関やベンダーから Fraggap 固有のIoCが出ているわけでもない。したがってここでは特定の検知手順ではなく、方針だけを述べる。

・不審な core_pattern の書き換え(| で始まる見慣れないヘルパー指定)が無いか、cat /proc/sys/kernel/core_pattern で確認する
・カーネルログ(dmesg / journal)に、原因不明のOops・skb関連の警告・不自然なプロセスのクラッシュが記録されていないか確認する
・想定外に生成された setuid バイナリや、権限が昇格したアカウントが無いかを棚卸しする
・疑わしい兆候があり、かつマルチテナントで影響が大きい場合は、確実なのは信頼できる状態への再構築である

「痕跡が見つからない」ことは「侵害されていない」ことの証明にはならない——この点は、カーネルLPEでは特に強く意識しておく必要がある。

対策の優先度まとめ

優先度 やること 位置づけ
最優先 カーネル更新 → 再起動(またはライブパッチ) 唯一の恒久対策
非特権ユーザー名前空間の無効化(user.max_user_namespaces=0 コンテナ経由の攻撃面を削る緩和。rootless Podman等を壊す副作用に注意
IPv6経路を使わない運用(可能な環境のみ) IPv6側の実証経路のみ縮小。IPv4側は残るため更新の代替にならない
splice() の制限 writeupが「良い選択肢でない」と明言。非推奨

よくある誤解と正しい理解

確認・対策でつまずきやすい点を、事実とあわせて整理する。

よくある誤解 正しい理解
「ネットワーク越しに攻撃される」 ローカル権限昇格(LPE)。攻撃者はまず対象上でコードを実行できる非特権ユーザーである必要がある(AV:L)
「IPv6を無効にすれば完全に安全」 実証されたIPv6経路(53362)は塞げるが、IPv4側の同一バグ(53366)は残る。恒久対策は更新
disable_ipv6 を1にしたから該当しない」 実行時の無効化はインターフェースの通信を止めるだけ。カーネル内のIPv6コードは残ることが多い。確実な非該当は # CONFIG_IPV6 is not set
「コンテナの中だから隔離されている」 Red Hatはコンテナエスケープとして整理。カーネルR/WはSELinuxより下位で、隔離を越えてホストrootに達しうる
「カーネルパッケージを更新したので対応完了」 稼働カーネルは再起動(またはライブパッチ)まで古いまま。uname -r で実測する
「CVSSが7.8だから緊急ではない」 数値はローカル前提を反映しているだけ。安定した公開エクスプロイトが存在し、共用ホストやコンテナ環境では実質的な緊急度は高い
「痕跡が見つからないので侵害されていない」 カーネルLPEは痕跡が残りにくい。確認できないことを「問題なし」と読み替えない

他の情報源との使い分け

本記事は「Linuxカーネル 権限昇格」というテーマの、個別CVEに対する実務判定編にあたる。Linuxカーネルの権限昇格は日本語でもニュースとして報じられることが多いが、役割が違うので併読を勧める。

情報源 強み この記事との関係
発見者writeup(@_qwerty_po) 一次情報。root cause とエクスプロイト手法の詳細 本記事の技術的事実はここに準拠。ただし攻撃再現の具体値は本記事では扱わない
NVD / kernel.org CNA CVEの正式な定義・スコア・修正コミット 影響範囲と修正の裏取りに使用
Red Hat RHSB-2026-009 ベンダーによる影響整理(コンテナエスケープ・緩和策) 深刻度・緩和策の根拠
ディストリのセキュリティトラッカー 自分のカーネルの Fixed / Not affected 手順3での最終判定に使用

同じ「自分が影響範囲かを判定する」構成のセキュリティ記事として、Linuxカーネルのローカル権限昇格を扱ったCVE-2026-46331「Pedit COW」解説|Linuxカーネルtcの欠陥でローカルからroot奪取、確認方法の落とし穴に踏み込んだwp2shell解説|WordPress事前認証RCEを自分のサイトで確認する実行コマンド、条件付きCVEの見極めを扱ったnginx 2026年6月のCVE 3件解説|Critical 2件は条件付き、自分が対象か判定する手順も同じ方針で書いている。

まとめ

Fraggap(CVE-2026-53362)は、IPv6のUDP corking経路で fraggap の会計が食い違い、MSG_SPLICE_PAGES が最後の安全弁を外すことで、skb_shared_info に最大15バイトのOOB書き込みが起きる脆弱性だ。そのわずかな上書きが、nr_frags の反転 → ダングリングページ → ページテーブル奪取(Dirty Pagetable)という確立した手筋を経て、安定したroot昇格・コンテナエスケープにまで到達する。

実務上の要点を3つに絞る。

  1. 性質を正しく捉える。 これはリモートRCEではなくローカル権限昇格(LPE)。だが共用ホストやコンテナ環境では、隔離を破る一手として深刻。Red Hatはコンテナエスケープとして Important に位置づけている
  2. 判定は「番号」でなく「修正の取り込み」で行う。 uname -rCONFIG_IPV6 を確認し、最終判断はディストリのセキュリティトラッカーで。IPv6が # not set なら実証経路は非該当だが、IPv4側(CVE-2026-53366)は別途更新が要る
  3. 恒久対策は更新と再起動だけ。 非特権ユーザー名前空間の無効化はコンテナ経由の緩和になるが rootless Podman を壊す副作用がある。IPv6無効化や splice() 制限は代替にならない(後者はwriteup自身が非推奨)

修正のメインライン取り込みから公開エクスプロイトまで1か月弱だった。カーネルの脆弱性では、修正コミットそのものが攻撃のヒントになる。番号を眺めて安心せず、自分の稼働カーネルを実測し、更新して再起動するところまでを一続きで完了させてほしい。

参照ソース

Fraggap writeup(研究者 @_qwerty_po / @physicube による一次ソース・2026年7月20日)
NVD — CVE-2026-53362(ipv6: account for fraggap on the paged allocation path)
NVD — CVE-2026-53366(ipv4側の同一バグ)
RHSB-2026-009 IPv6 Fragmentation Container Escape(Red Hat・ipv6_frag_escape)
CVE-2026-53362(Ubuntu Security)