GhostLock、15年もの間すべてのLinuxに潜み続けたスタックUAFの亡霊

「悪魔は細部に宿る」とはよく言ったものです。

数行のコードの思い込みが、15年ものあいだ見過ごされ続けた大穴を生む、それが、2026年7月にNebula Securityによって公表されたLinuxカーネルの脆弱性「GhostLock」(CVE-2026-43499)です。

この脆弱性は、特別な権限やカーネル設定を必要とせず、ローカルの攻撃者にroot権限をもたらす深刻なものでした。

影響範囲はLinux 2.6.39から7.1まで、つまり2011年以降のほぼすべてのメジャーなディストリビューションが該当します。

GhostLockの正体、rtmutexとプロキシのすれ違い

GhostLockは、リアルタイムミューテックス(rtmutex)のコードに潜むスタックUse-After-Freeです。

きっかけは、futex(2)システムコールの「Requeue-PI」機能にあります。

futexは高速なユーザー空間ロックの仕組みですが、その裏でカーネルが複雑な優先度継承(PI)処理を行っています。

具体的には、あるスレッドがFUTEX_WAIT_REQUEUE_PIで待機するとき、カーネルスタック上に「rt_mutex_waiter」という構造体を作ります。

通常、ロックの獲得は自分自身で行いますが、FUTEX_CMP_REQUEUE_PIを使うと、待機中の別スレッドのwaiterを、代理で別のfutexに繋ぎに行く(プロキシ)ことができます。

この代理操作中にデッドロックが検出されると、設定を巻き戻すためremove_waiter()が呼ばれます。

ここに落とし穴がありました。

remove_waiter()は、「いま実行中のスレッド(currentマクロ)が、そのwaiterの持ち主だ」と信じて疑いません。

通常のパスでは正しいのですが、プロキシ経由ではcurrentは「代理を頼んだスレッド」であり、実際のwaiterは別のスレッドに属しています。

その結果、誤ったスレッドのpi_blocked_on(PIの待ち状態を指すポインタ)をNULLクリアしてしまい、本来のwaiterを持つスレッドは、スタックが解放された後もダングリングポインタを抱えたままになります。

この取り残されたポインタが、後続のPIチェーン処理で不正に参照され、Use-After-Freeが成立します。

この見落としが15年も生き延びた理由の一つに、カーネルのデバッグ機構「lockdep」が検知できなかった点があります。

lockdepはpi_lockの獲得と解放の整合性を監視しますが、間違ったスレッドで操作されても、ロックのルール自体は守られているように見えてしまうのです。

悪用の手口、スタックUAFからrootへ

攻撃者は、このダングリングポインタを足がかりに、カーネルの制御を奪います。

大まかな流れは以下の通りです。

まず、解放されたスタック領域を巧妙に「再取得」するため、CEAスプレー(Control-flow Enforcement by Allocation)と呼ばれる手法で、カーネルスタックの内容を任意のデータで上書きします。

これにより、あたかも偽のwaiter構造体がそこに存在するように見せかけ、pi_blocked_onのチェーンを操作します。

次に、PR_SET_MM_MAPというシステムコールを利用し、その偽waiterを起点に限定的ながら任意のアドレスへ書き込む権限を得ます。

ターゲットとして選ばれるのが、inet6_protosというIPv6プロトコルハンドラの関数テーブルです。

ここを書き換えて、カーネルの制御フローを乗っ取ります。

その後、ROP(Return-Oriented Programming)チェーンを組んで権限昇格を達成します。

GoogleのkernelCTFでは、この攻撃が驚異の97%という高い成功率で実証され、$92,337の報奨金が支払われました。

修正と教訓

修正はごく単純で、remove_waiter()内でcurrentのpi_blocked_onを触るのではなく、waiter->task->pi_blocked_onを正しく操作するように変更するだけです。

該当パッチは2026年4月にLinux 7.1-rc1に取り込まれました。

また、CONFIG_RANDOMIZE_KSTACK_OFFSETやSTATIC_USERMODE_HELPERといった、より新しいカーネル強化機能が間接的な緩和策となります。

しかし、根本的には、長く使われてきたヘルパー関数の「暗黙の前提」が、新たなコールパスによって崩されたことが原因でした。

コードの一片が、かくも長い時間を経てようやく白日の下に晒される。

ソフトウェアの信頼性とは、そうした地道な検証と修正の積み重ねの上に成り立っているのかもしれません。

記事一覧
GhostLock、15年もの間すべてのLinuxに潜み続けたスタックUAFの亡霊 | Kotaro Asahina