Dirty FragはCopy Fail対策後も残るLinuxページキャッシュ権限昇格だった
目次
TL;DR
影響 LinuxカーネルのESPとRxRPCまわり。通常ユーザーからrootへ上がるローカル権限昇格で、コンテナ基盤ではホスト侵害の入口
対応 ディストリビューションの修正済みカーネルへ更新。ESP側はCVE-2026-43284として追跡され、上流mainlineにも修正済み
暫定 esp4、esp6、rxrpc のロード禁止。IPsec ESPやAFSを使う環境では影響確認が先
Dirty Fragは2026年5月7日に公開されたLinuxカーネルのローカル権限昇格だ。
ESP側はCVE-2026-43284になり、RxRPC側はV4belのwrite-upではCVE-2026-43500が予約済みとされているが、公開直後はベンダー側の追跡状況がまだ揃っていない。
先月のCopy Failで algif_aead を無効化した環境でも、Dirty Fragは別経路で刺さる。
同じページキャッシュ汚染の系統だが、今回はAF_ALGではなく、ネットワーク側の struct sk_buff のfragにページキャッシュ由来のページが入り、そのまま暗号処理で書き換えられる。
V4belのDirty Frag write-upでは、xfrm-ESP Page-Cache WriteとRxRPC Page-Cache Writeをつないで主要ディストリビューションの盲点を埋める形になっている。
単体のバグ名というより、ページキャッシュ参照をネットワークバッファのfragへ渡したあと、受信側の暗号処理がin-placeでSTOREしてしまうバグクラスとして読んだほうが分かりやすい。
ページキャッシュを書き換える先がAF_ALGからskb fragへ移った
Copy Failは splice(file -> pipe -> AF_ALG) で、読み取り権限しかないファイルのページキャッシュを暗号APIのscatterlistへ差し込んだ。
authencesn の処理中に4バイトのSTOREが走り、/usr/bin/su のようなsetuid-rootバイナリのメモリ上コピーだけが汚れる。
Dirty Fragでも狙いは近い。
ディスク上のファイルではなく、LinuxがRAM上に保持しているページキャッシュへ書く。
違うのは、ページキャッシュの参照が AF_ALG ではなく、UDPやRxRPCの送受信で使われる sk_buff のfragへ入る点だ。
sk_buff はLinuxネットワークスタックのパケット表現で、線形領域だけでなく、ページ単位の断片をfragとしてぶら下げられる。
splice() や MSG_SPLICE_PAGES が絡むと、コピーなしでページを渡せる。
この「コピーなし」が性能には効くが、受け側があとで中身を書き換えるなら、先にコピーオンライトでカーネル専用のページへ逃がす設計になる。
Dirty FragのESP経路では、この逃がし方が足りなかった。
UbuntuのCVE-2026-43284ページやNVDのCVE-2026-43284ページに載っている説明では、IPv4とIPv6のdatagram append経路がUDP skbへsplice由来ページを入れるとき、TCP側のように SKBFL_SHARED_FRAG を立てていなかった。
そのせいでESP入力は「共有ページではない普通のnonlinear skb」と見なし、no-COWの高速経路でin-place復号してしまう。
flowchart TD
A["読み取り可能なファイル"] --> B["spliceでpipeへ渡す"]
B --> C["MSG_SPLICE_PAGESで<br/>UDP skbのfragへ入る"]
C --> D["ESPまたはRxRPCの<br/>受信側暗号処理"]
D --> E["コピーオンライトせず<br/>in-place STORE"]
E --> F["ディスクではなく<br/>ページキャッシュが汚れる"]
F --> G["setuid実行や認証処理が<br/>汚れた内容を見る"]
この図の最後がきつい。
ファイル本体のハッシュは変わらない。
でも execve() や read() がページキャッシュ上の改変済み内容を見るため、攻撃者はroot昇格へつなげられる。
ESP側は4バイトをかなり直接書ける
ESPはIPsecのEncapsulating Security Payloadで、暗号化と認証付きの通信を扱う。
Dirty FragのESP側では、ESP-in-UDPの受信経路が esp_input() に入り、authencesn(hmac(sha256), cbc(aes)) の復号処理へ進む。
問題は、esp_input() が「cloneされていない、frag_listもないnonlinear skb」を安全だと見て skb_cow_data() を飛ばすところにある。
fragの中身がsplice由来のページキャッシュでも、そのままsrcとdstを同じscatterlistとして暗号処理へ渡す。
V4belの解説では、ESN(Extended Sequence Number、IPsecで64ビットのシーケンス番号を扱う仕組み)の前処理で4バイトのSTOREが発生する。
攻撃者はXFRM SA登録時の seq_hi を通じて書き込む4バイトを制御でき、payload長を調整して書き込み先オフセットも合わせられる。
認証に失敗しても、STOREは先に実行済みなのでページキャッシュの汚染が残る。
ただし、このESP経路を起動するにはXFRM SAを登録する必要があり、通常は CAP_NET_ADMIN が要る。
多くの環境ではユーザー名前空間とネットワーク名前空間を作って、その中のcapabilityで到達する。
Ubuntuの一部構成ではAppArmorが非特権ユーザー名前空間を制限するため、この経路だけでは踏めない場合がある。
RxRPC側はUbuntuの穴を埋める
RxRPCはAFS(Andrew File System)などで使われるRPCプロトコルだ。
Dirty FragのRxRPC側では、rxkad_verify_packet_1() が受信パケットの先頭8バイトをin-placeで復号する。
ここでもskb fragにページキャッシュ由来のページが入っていると、8バイトのSTOREがそのページへ落ちる。
ESP側と違って、RxRPC側はユーザー名前空間を作らなくてもよい。
V4belの説明では、RxRPC v1 tokenの session_key を通常ユーザーが add_key("rxrpc", ...) で登録でき、その鍵を使って fcrypt の復号結果をページキャッシュへ書かせる。
この経路は書き込む8バイトを直接選べるわけではない。
攻撃者はユーザー空間で鍵を総当たりし、欲しい平文に近い復号結果が出る鍵を探す。
V4belのPoCは /etc/passwd のroot行を狙い、少ない制約のバイトだけを合わせて、PAMの nullok 設定がある環境で空パスワード扱いに寄せる。
2つをつなぐ理由はここにある。
ESP側は強い4バイト書き込みだが、ユーザー名前空間の制限に当たる環境がある。
RxRPC側は書き込み値の制御が弱いが、Ubuntuのように rxrpc.ko が使える環境で名前空間制限を避けられる。
片方の穴をもう片方で補うので、単一ディストリビューションの設定だけを見て安心しづらい。
Copy Failの緩和では塞がらない
Copy Failの暫定策は algif_aead の無効化だった。
Dirty Fragは algif_aead を通らない。
V4belのREADMEも、Copy Failの公開済み緩和を入れたLinuxでもDirty Fragには残ると明記している。
ページキャッシュ汚染という結果は似ているが、入口は別物だ。
Copy FailはLinuxのユーザー空間向け暗号ソケット AF_ALG が入口だった。
Dirty FragはIPsec ESPとRxRPCの受信処理が入口になる。
CanonicalのDirty Frag mitigation記事では、影響コンポーネントとしてESPとRxRPCのkernel moduleを挙げ、両方を無効化しないと片方が残るとしている。
また、コンテナで任意の第三者ワークロードを動かす環境では、ローカル権限昇格に加えてコンテナ脱出シナリオを助ける経路にもなり得る、と書いている。
PoCがそのままコンテナ脱出として公開されている、という意味ではない。
同じホストカーネル上で信頼できないコードを走らせるなら優先度が上がる、という話だ。
修正はshared fragを見てCOWへ落とす
ESP側の修正は、splice由来の共有fragに SKBFL_SHARED_FRAG を付け、ESP入力側でそのフラグが立っている場合は skb_cow_data() へ落とす形だ。
V4belのREADMEは2026年5月8日更新として、CVE-2026-43284が上流mainlineの f4c50a4034e6 で修正済み、RxRPC側はCVE-2026-43500として予約済みだがツリー上の修正はまだない、としている。
NVDではCVE-2026-43284について、CISA-ADPのCVSS 3.1が7.8 HIGH、ベクターは AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H になっている。
NVD自身の評価は記事作成時点で未提供だが、kernel.org由来の説明とstable patch参照は入っている。
Ubuntuは2026年5月8日の時点で、TrustyからResoluteまでのUbuntu releaseを影響ありとして掲載していた。
手動緩和は /etc/modprobe.d/dirty-frag.conf を作って esp4、esp6、rxrpc のロードを止め、必要ならinitramfs更新とモジュールのunload、unloadできない場合は再起動、という流れだ。
echo "install esp4 /bin/false" | sudo tee /etc/modprobe.d/dirty-frag.conf
echo "install esp6 /bin/false" | sudo tee -a /etc/modprobe.d/dirty-frag.conf
echo "install rxrpc /bin/false" | sudo tee -a /etc/modprobe.d/dirty-frag.conf
sudo update-initramfs -u -k all
sudo rmmod esp4 esp6 rxrpc 2>/dev/null
この緩和は副作用がある。
esp4 と esp6 はIPsec ESPに関係するので、StrongSwanのようなIPsec VPNを使っているホストでは通信が壊れる。
rxrpc はAFSやRxRPC利用アプリケーションに影響する。
一般的なWebサーバーや開発サーバーでは使っていないことも多いが、VPNゲートウェイや古い分散ファイルシステムが絡む環境では雑に入れないほうがいい。
確認は uname -r だけでは足りない。
ディストリビューションは上流バージョンを上げずに修正をバックポートする。
Debianのsecurity trackerのように、同じCVEでもreleaseごとにfixed versionがずれる。
実際に使っているカーネルパッケージのadvisoryまで見る。
汚染後のページキャッシュは残る
V4belのREADMEは、PoC実行後にページキャッシュが汚染されるため、drop_caches か再起動で掃除するよう注意している。
これは防御側の検証でも厄介だ。
「脆弱かどうか試す」つもりで本番にPoCを投げると、setuidバイナリや /etc/passwd のメモリ上コピーを自分で汚してしまう。
疑わしいホストでPoCを実行して確認するより、先にモジュールロード状態、ユーザー名前空間、カーネルパッケージの修正状況を見るほうがいい。
ページキャッシュ汚染は再起動で消える一方、攻撃者がrootを取ったあとに置いた永続化は別問題として残る。
Dirty Fragそのものがディスクを直接書き換えないからといって、侵害後のファイルや認証情報まできれいなままとは限らない。