ホームへ戻る

推論系統安全

llama.cpp b11000、無効な計算グラフを消去し、認証不要のRPCリモートコード実行脆弱性を修正

llama.cppのRPCサーバーは、解放済みバッファを指し続けるキャッシュ済み計算グラフを再実行していたため、リモートクライアントが読み書き能力を獲得し、コードを実行できる可能性があった。b11000ではバッファ解放時に関連するグラフ状態を破棄するが、RPC自体を信頼できないネットワークへ直接公開することは依然として推奨されない。

The GGML authors · Public domain · Image source
zh-Hant

llama.cppは9月16日、b11000プレリリース版を公開し、`ggml-rpc-server`のuse-after-freeを修正した。RPCバックエンドはデバイスごとに直近の計算グラフを保持し、クライアントがテンソルデータを再送信せずに`GRAPH_RECOMPUTE`で再実行できるようにしている。問題は、グラフノードがバックエンドバッファへの直接ポインタを保持していたことにある。クライアントが`FREE_BUFFER`を呼び出してもキャッシュ済みグラフは無効化されず、再実行するとダングリングポインタをたどって解放済みメモリにアクセスしてしまう。

プロジェクトのリリースノートによると、攻撃者は認証なしでこの処理経路を呼び出すことができ、その後の`ALLOC_BUFFER`と`SET_TENSOR`を通じて、解放されたメモリ領域を再構成できる。計算グラフによって得られる読み書き能力を利用してlibcのアドレスを漏えいさせ、さらに`BUFFER_CLEAR`が使用するbuffer interface vtableを乗っ取ることで、最終的にRPCサーバープロセスの権限で任意のコードを実行できる。これは推論をクラッシュさせるだけのサービス拒否(DoS)問題ではなく、分散推論ノードのホストが乗っ取られるリスクである。

b11000の対処方法は比較的単純だ。`free_buffer()`の実行時にキャッシュ済み計算グラフを消去し、その後の`graph_recompute()`では既存のnullチェックによってリクエストを拒否する。クライアントは完全な`GRAPH_COMPUTE`へフォールバックする。この修正ではプロトコルやAPIに変更がないため、通常、アップグレードに際して呼び出し側を変更する必要はない。運用者はb11000以降を使用し、コンテナイメージ、静的バイナリ、ダウンストリームアプリケーションに古いコミットが引き続きバンドルされていないか確認すべきだ。

防御はアップグレードだけで終わらせてはならない。llama.cppのセキュリティポリシーでは、信頼できないネットワーク上でRPC backendまたは`ggml-rpc-server`を使用しないよう明確に推奨している。実際のデプロイでも、ファイアウォール、プライベートネットワーク、プロセスの権限低下、コンテナ隔離によって到達可能性を制限すべきだ。今回のバージョンはプレリリース版であり、公式ページにもCVSS、影響を受けるバージョンの下限、完全な独立検証データは掲載されていない。今後、正式なセキュリティアドバイザリが追加公開されるか、派生パッケージが修正を迅速に取り込めるかを注視する必要がある。

出典

  1. Release b11000 · ggml-org/llama.cpp
  2. llama.cpp patches an unauthenticated RPC use-after-free that yields remote code execution
  3. ggml-org/llama.cpp b11000 release mirror