Linuxカーネル新脆弱性、root所有ファイルが読まれる

Linuxカーネル新脆弱性、root所有ファイルが読まれる

非特権ユーザがSSHホスト秘密鍵や/etc/shadowを読める脆弱性が公表され、公表時点ではすでに修正コミットがマージされていた。安定版カーネルすべてが影響を受け、5年前にも同じ形がメーリングリストで指摘されていた。


報告と同日にリーナス・トーバルズが修正

Linuxカーネルに、非特権ユーザがroot所有ファイルを読み出せる脆弱性が見つかっている。Qualys(クオリス)が security@kernel に報告し、リーナス・トーバルズ(Linus Torvalds)が修正コミット 31e62c2ebbfd をマージした。5月14日以前のすべての安定版カーネルが影響を受ける。

被害の輪郭がはっきりしている。SSHホスト秘密鍵(/etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key、モード0600)が抜かれる。/etc/shadow も読まれる。rootハッシュをオフラインで解析されれば、特権昇格はその先にある。

ローカルアカウントを持つ攻撃者なら誰でも条件を満たす。共有サーバ、CIランナー、コンテナホスト、踏み台、SSHアクセスを許す環境すべてが射程に入る。

ssh-keysign-pwn — pre-31e62c2ebbfd kernels(2026年5月14日時点で安定版すべて)が影響を受ける。

__ptrace_may_access() の取りこぼし

問題はカーネルの __ptrace_may_access() という関数にある。プロセスが別プロセスの内部を覗ける条件を判定する番人だ。ここに条件分岐の穴があった。

スレッドが終了するときや、カーネルスレッドのように task->mm == NULL(メモリディスクリプタが存在しない)状態のとき、関数は dumpable チェックを丸ごとスキップする。本来であれば、root権限で開かれたファイルを子プロセスから覗ける状況かどうかを慎重に判定すべき場面で、判定そのものが省かれていた。

実装の都合と被害の規模が噛み合っていない。Cで書かれたカーネルなら起こりうる種類のロジックバグだが、影響範囲は安定版のすべてだ。

終了処理の隙間を pidfd_getfd で突く

エクスプロイトの手順は単純で、だからこそ厄介だ。プロセスが終了するとき、カーネルは do_exit() を実行する。その内部で exit_mm()(メモリディスクリプタの解放)が exit_files()(ファイルディスクリプタの解放)よりも先に走る。

このわずかな時間差のあいだに task->mm は NULL になるが、ファイルディスクリプタはまだ生きている。攻撃者はこの窓を狙って pidfd_getfd(2) を呼び出し、終了処理中のプロセスからファイルディスクリプタを横取りする。呼び出し元のuidが対象と一致していれば成功する。

窓は短い。だが繰り返せば必ず開く。

終了途中のプロセスから、まだ開いたままのファイルディスクリプタを抜き取る。設計上の前提が、ここで崩れている。
プロセス終了の隙間で攻撃が成立するまで
STEP 1
カーネルプロセス終了開始
対象プロセスが do_exit() に入り、終了処理が走り始める。
STEP 2
カーネルメモリ解放、窓が開く
exit_mm() によって task->mm が NULL になる。__ptrace_may_access() は dumpable チェックを丸ごとスキップする。
STEP 3
攻撃者FDを横取り
同じuidで pidfd_getfd(2) を呼ぶと、root権限で開かれた SSHホスト秘密鍵や /etc/shadow のFDを掴める。
STEP 4
カーネルFD解放、窓が閉じる
exit_files() でFDが解放され、窓は閉じる。だが攻撃者の手元にはFDの複製がすでに残っている。
※ STEP 2〜3 が攻撃の成立窓。uidが対象プロセスと一致するローカルアカウントが条件。

標的になった2つのバイナリ

PoC(概念実証コード)は2つの古典的なバイナリを狙う。設計は20年以上前から変わっていない。

ssh-keysign は、OpenSSHがホスト認証の署名に使うヘルパーバイナリだ。秘密鍵ファイル(モード0600、root所有)を開き、そのあとで permanently_set_uid() を呼んで権限を落とす。sshd_configEnableSSHKeysign=no で抜けるパスでは、ファイルディスクリプタを開いたままバイナリが終了する。この設計は2002年からそのままだ。

chage は、ユーザのパスワード有効期限を扱うコマンドで、/etc/shadow を読む。chage -l <user>spw_open(O_RDONLY) を呼んだあと setreuid(ruid, ruid) を実行する。両方の引数を実uidに揃えることでuid・euid・suid・ruidすべてが揃い、完全な権限ドロップになる。終了処理を競争相手にして、shadowのファイルディスクリプタを抜き取り、rootのハッシュをオフラインで解析する流れだ。

カーネル側の論理エラーが、ユーザランドの長年の慣行をそのまま武器に変えた。SSHやshadow-utilsのバグではない。カーネルが既存のFDハンドリングを抜け道に変えてしまった。

ヤン・ホルンが5年前に警告していた

最も重いのは時系列だ。2020年10月、Google Project Zeroのヤン・ホルン(Jann Horn)が、ほぼ同じFD窃取の形をLKML(Linuxカーネルメーリングリスト)に投げていた。パッチ案も添えられていた。

しかしマージはされなかった。誰かが反対したわけでもなく、議論が止まり、忘れられた。5年の歳月が流れた。

Qualysが今回あらためて指摘し、トーバルズが数時間で修正をマージした。修正できるパッチが5年間、メーリングリストのアーカイブで眠っていたわけだ。

脆弱性は技術ではなく、運用の問題で残ることがある。今回はその典型例だ。

5月の連続インシデントが意味するもの

2026年5月のLinuxカーネル界隈は穏やかではない。Copy Fail、Dirty Frag、Fragnesia、そしてssh-keysign-pwn。いずれも安定版のすべてに影響し、いずれもrootを取られる。

2026年4月末から続く Linuxカーネル脆弱性 4件
通称 公表日 バグの種類 到達点
Copy Fail
CVE-2026-31431
4月29日 algif_aead の
ページキャッシュ書込
root権限昇格
Dirty Frag
CVE-2026-43284
CVE-2026-43500
5月7日 ESP/rxrpc の
復号インプレース
root権限昇格
Fragnesia
CVE-2026-46300
5月13日 ESP-in-TCP の
ページキャッシュ書込
root権限昇格
ssh-keysign
-pwn

CVE未割当
5月14日 ptrace の
論理バグ
root所有ファイル
読出
※ ssh-keysign-pwn のみ権限昇格ではなく機密ファイルの読出。他3件は setuid バイナリ経由で root シェルに到達する。

ssh-keysign-pwnは他3つとは性格が異なる。Copy Fail以下はページキャッシュやネットワークスタックの細工で書き込みを成功させるタイプだったが、今回は純粋な論理バグだ。ファイルディスクリプタの所有関係を判定する関数の、たった1つのスキップ条件が裏目に出た。

修正コミットを取り込んだカーネルへのアップデートが当面の対策となる。共有環境を運用している側にとっては、いつ非特権アカウントがroot権限まで届くかという話に直結する。

カーネルの中で20年以上動いてきた古い設計に、2020年、警告が届いていた。穴がふさがるまで、5年かかった。


参照元

関連記事

この記事を共有する