サーバセキュリティ

CVE-2026-98432 の概要と周辺情報 (MPTCP, UAF) と影響・緩和策について

はじめに

先日、Anthropic 社が公開した研究レポートを発端に、Linux カーネルの深刻な脆弱性 CVE-2026-98432 が大きな注目を集めました。

「AI(Claude)が自律的に発見し、MPTCP のリスナーに対するパケット送信から root 権限の奪取 (RCE) に至った」という鮮烈な実証の裏側で、1 つの疑問が浮上しました。

piyokango さんのまとめにもありましたが、

Linuxカーネルの脆弱性 CVE-2026-98432 についてまとめてみた - piyolog
2026年10月15日、LinuxカーネルのCNAは、IPv4のTCP処理にある...

*1:Anthropicのレポートが示しているのは、MPTCPのリスナーへのパケット送信でrootでのコマンド実行に至った実証と、基になる脆弱性が CVE-2026-98432 であることまで。CVEの説明文と修正コミットにはMPTCPの記載がない。

この部分をどう読み解けばよいのか、解説の記事が無かったので AI 壁打ちのもと整理してみました。

バグ修正箇所は MPTCP ではなく「コア IPv4 TCP」

まず大前提として、CVE-2026-98432 は MPTCP のバグによるものではなく、コア IPv4 TCP 処理のバグによるものです。

修正コミットは 2 つですが 1 つ目はnet/ipv4/tcp_ipv4.c および af_inet.c の修正、2つ目は net/ipv4/inet_connection_sock.c です。net/mptcp の修正はありません。

ipv4: free inet_opt and ireq_opt after an RCU grace period ?? torvalds/linux@e3f33b0
tcp_v4_syn_recv_sock() transfers ownersh...
tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitting SYN+ACKs. ?? torvalds/linux@c905dee
As with the preceding patch, this patch ...

また、2 つ目については [TCP request socket migration (net.ipv4.tcp_migrate_req)] に関する修正で、本機能はデフォルトで OFF のため、通常は影響を受けません。

1 つ目のリンクには以下の通り記載されています。

Since commit 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table"), request sockets are processed without holding the listener lock, so nothing prevents the child socket from being freed while the SYNACK is still being built. TCP child sockets do not have SOCK_RCU_FREE, and inet_sock_destruct() frees inet_opt with a plain kfree(), leading to a use-after-free in ip_options_build().

commit 079096f103fa 以降、use-after-free を引き起こす状態であったことが記載されています。

今回の commit e3f33b0a1d89 にて kfree を kfree_rcu に置き換えることで、他の CPU の読み込みがいなくなってから kfree する、といった処理に変わります。

MPTCP とは

MultiPath TCP という機能で、主な利用シナリオとしてはスマホの WiFi と LTE を仮想的な 1 つの TCP ストリームとして扱うことができ、WiFi が切れて LTE に切り替わっても一からやり直すことなく通信が継続できる機能です。

これはクライアント側もサーバ側も対応している必要があり、tcp syn, syn/ack のときに TCP オプション (MP_CAPABLE) で MPTCP が使えることを提示し合う必要があります。

例えば WiFi でベースとなる TCP コネクション確立後、LTE で2 本目の TCP コネクションはサブフローと呼ばれ、MP_JOIN オプションのサブタイプによって既存の TCP ストリームに合流します。

Use After Free のおさらい

Use After Free (UAF) は free された heap 領域に関するポインタが残されている状態でそれが意図的に呼び出せることで発生する不具合です。

典型的な攻撃としては以下のようなものです。

  1. heap 領域 A に構造体 (関数ポインタ含む) を配置しポインタ a にアドレス格納
  2. 構造体を free
  3. 悪意ある入力により heap 領域 A に悪意ある関数ポインタを含む別の構造体を配置
  4. ポインタ a を経由して意図せず悪意ある関数ポインタを呼び出し

今回の脆弱性についていえば、細工された IP パケットが「悪意ある入力」で、意図せず呼び出してしまうのは ip_options_build() 内の処理です。

一般に malloc() でメモリ確保、free() でメモリ解放しますがメモリ管理機能にその領域が空いていることを伝えるだけであり、ポインタ (アドレス変数) は一緒には消えません。

そして free() で解放直後に malloc() を同じサイズで確保すると一般には解放された場所がそのまま再利用されます。

プログラミングの流れによってはこれがうまく嚙み合うと意図しない攻撃に結び付けられます。

anthropic の PoC 内容

以下の「5. Zero-click remote code execution in Linux」が該当箇所。

Discovering and exploiting vulnerabilities in critical, real-world software with Claude
Over the past few months, we’ve used an ...

Claude wrote an exploit that allows a remote attacker to send packets to Linux servers with a multipath TCP listener to run arbitrary commands as root, without any credentials or user interaction.

とのことで、やはり MPTCP でソケットを開き Listen した状態から root を奪ったことが分かります。

The underlying vulnerability is a race condition-induced UAF bug in the kernel networking stack. 

ここで競合状態 (race condition) に起因する Use After Free が根本の脆弱性と分かります。

今回の exploit は 2 つのステージに分かれます。

1st stage は KASLR の突破です。

  • In the first stage, the attacker defeats KASLR remotely. It exploits the race to make the kernel read an attacker-controlled length field to copy extra bytes and send them back to the attacker, and as long as one such overread contains a kernel pointer in the reply, the attacker learns the kernel address space layout.

KASLR とは、カーネルアドレス空間のランダム化で、起動のたびに場所が変わります。この機能が OFF の場合、カーネルに展開される関数などの論理アドレスはバージョンに依存するため、バージョンが分かれば攻撃に利用できる関数をアドレス指定できます。ON の場合、kernel 起動のたびに展開先の論理アドレスが変わるため攻撃者は推測ができなくなります。

これを突破するには、何かよく知られた関数などのポインタ (論理アドレス) をリークさせる必要があります。そのよく知られた関数から攻撃で利用できる関数の論理アドレス差は環境によって変わらないので、結果攻撃で利用できる関数の論理アドレスが分かる、ということです。

今回は UAF により被害者側の Linux が送信予定の IP パケットのヘッダの Length フィールドを大きい値に上書きし、被害者 Linux はその Length を信じて本来送ろうとしたパケットの範囲を超えたカーネル領域を読み込み、攻撃者に送信させます。その中に何かしら特定の関数の論理アドレスと思われるものが入っていればそこから攻撃に利用できる関数のアドレスが計算できるものと思われます。これができれば 2nd stage に移れます。

ここまでが KASLR の突破です。

2nd stage は実際に攻撃をします。

  • In the second stage, the attacker hijacks the control flow. It exploits the same UAF bug to overflow a buffer and overwrite a callback pointer with the address of a payload the attacker has already staged in kernel memory via an ordinary protocol feature. When the kernel invokes the callback, the payload chains a series of calls to existing kernel functions. ending with an attacker-chosen shell command running as root.

1st stage と同じ UAF により、callback pointer を攻撃に利用できる関数と引数がうまく実行されるように上書きします。そして kernel がその callback を呼び出したときに root シェルを獲得できる、という流れです。

「with the address of a payload the attacker has already staged in kernel memory via an ordinary protocol feature.」というのはやや気になる表現で、「通常のプロトコル機能を通してカーネルメモリ上にペイロード (悪意あるコード、今回は攻撃に利用できる関数と引数を指してると思われる) 上に用意しておく」と訳せます。ペイロードをステージングするのはよくある方法ですが、それ用の領域が必要になります。敢えて「via an ordinary protocol feature」と断りを入れてるのは MPTCP オプション領域を使ったことを暗示しているようにも思えました。

今回の脆弱性のポイント

概要は NVD に記載されていますが、

NVD - Home

inet_sock_destruct() や tcp_v4_reqsk_destructor() の関数の中で kfree() が使用されており、ip_options_build() の中で use-after-free に至る、と記載されています。

ここで almalinux.org のブログを見ると

CVE-2026-98432: Patched kernels available in testing
A new Linux kernel vulnerability, CVE-20...

The bug can only be triggered by a TCP connection request that carries IPv4 options.

とあります。

今回のアンソロピックの PoC では MPTCP を使ったことが明記されていますが、これは TCP オプションです。IP オプションを付けたという記述はありませんが、このブログを信じるなら実際には付けていたはずです。実際、ip_options_build() は IP オプションが存在するときに呼び出されるようです。

とすると今回の脆弱性は IP オプションのポインタに関する UAF の脆弱性とも言えます。

そして逆に MPTCP を使う必然性は見当たりません。

ただ、競合状態に勝つ (※) 必要があるので、そのような状態が起こりやすい、処理が複雑となる MPTCP を使った、というのは 1 つ考えられるシナリオです。

※ 競合に勝つ = CPU0 が SYN を受け IP オプションを heap に読み込んだあと、CPU1 が再送の SYN により kfree を実施し悪意ある参照アドレスを埋め込み、その後 CPU0 が ip_options_build() により悪意ある参照アドレスを呼び出す、という状態にする

また、わざわざこの機能を使って PoC を行ったということは、これを使わずして攻撃成立ができなかった、と考えてもよいと思います。

今回の PoC では 1st stage (KASLR 突破) は 48 分、2nd stage (root シェル獲得) は 5 分掛かったようなので、条件の良い状態でそれくらいの時間が掛かった、という事実も見逃せません。

対処について

MPTCP の有効/無効の確認

TCP でインターネット公開している Linux についてはまずは MPTCP が有効になっているか確認します。Kernel の net.mptcp.enabled は 1 になっていても構いません。それよりも ss -Mnlp で MPTCP が有効になっている Listen ソケットが無いか確認します。

もし有効になっていたら緊急での対応が必要です。

なお、Go 1.24 以降で Go 標準の net パッケージを使ってビルドされたアプリは MPTCP が有効状態となるため、注意が必要です。

本格対処と暫定対処

本格対処としては kernel の本脆弱性修正リリース版へのバージョンアップ (要 OS 再起動) になります。

もし難しい場合は暫定対処 (緩和策) として IPv4 オプションを拒否するのが挙げられます。

IPv4 オプションはレガシーな技術であり、私も長年パケットキャプチャでパケットを見ていますが、付いているのを見たことがありません。拒否しても影響は無いと考えてよいでしょう。

前述の almalinux.org のブログでは IPv4 オプションを拒否する方法として以下が挙げられています。

$ sudo nft -f - <<'EOF'
add table ip cve_2026_98432
delete table ip cve_2026_98432
table ip cve_2026_98432 {
    chain prerouting {
        type filter hook prerouting priority -300; policy accept;
        meta l4proto tcp ip hdrlength > 5 counter drop
    }
}
EOF

 It works alongside firewalld and is safe to run more than once.

とのことなので firewalld と併存ができそうです。

もし MPTCP が使われていない場合であっても 2026/10/31 12:00 時点で攻撃が観測されているわけではありませんので緊急ではありませんが、冷静に計画しバージョンアップするのが望ましいです。ただし、攻撃が観測されたら緊急での対応が必要になります。

なお、対処としては FortiGate や PaloAlto 等で IP オプションが付いたパケットをドロップする、という守り方もあるかもしれません。(今後要調査)

また、本件に関しては SELinux を Enforcing にすることで被害を最小化でき、また、やり方によっては Permissive でも攻撃を検知できる可能性があります。(今後要調査)

まとめ

  • MPTCP の脆弱性ではないため、MPTCP が無効であっても攻撃は成功しうる。が、MPTCP 有効状態のサービスは攻撃を受けやすい。
  • MPTCP は OS レベルで有効になっていても、実際にサービス (apache, nginx 等) が MPTCP 有効状態でソケットを開いていなければ MPTCP を使った攻撃はできない。
  • MPTCP 有効状態でソケットを開いているかどうかは ss -Mlnp で確認可能。これで何も表示されないのに net.mptcp.enabled = 0 を設定するのはあまり意味をなさない。
  • Go 1.24 以降で Go 標準の net パッケージを使ってビルドされたアプリは MPTCP が有効状態となる。
  • 2026/10/31 12:00 時点において本脆弱性に関する実害におよぶ攻撃は観測されていない。
  • 現時点では冷静に kernel 修正リリース版の適用 (要 OS 再起動) を計画するのが望ましいが、攻撃が観測された場合は緊急の対応が必要。
  • IP オプションは現代ではほぼ使われないため nft でフィルターすることで暫定対処となる。FW アプライアンスで IP オプションを拒否する設定ができるかもしれない。(要調査)
  • SELinux を Enforcing で被害最小化、Permissive で攻撃検知ができる可能性がある。(要調査)

コメント

タイトルとURLをコピーしました