TRITON_BATCH_STRATEGY_PATH を介した任意の dlopentriton-inference-server/core のカスタムバッチ戦略ローダーにおける絶対パストラバーサル。モデル設定パラメータが検証されずに dlopen(RTLD_NOW | RTLD_LOCAL) に渡されるため、モデルの config.pbtxt に影響を与えられる者は誰でも、モデルロード時に Triton サーバープロセス内でネイティブコード実行を得られます。
NVIDIA は速報 5865 の中で次のようにそのまま記載しています: CVE-2026-47630: s1ko
Triton はモデルの config.pbtxt からモデルごとの TRITON_BATCH_STRATEGY_PATH パラメータを受け付けます。26.05 までは、この値は任意のファイルシステムパスとして扱われ、変更されずに dlopen に渡されていました。包含チェックも、許可リストも、署名またはハッシュの検証もありませんでした。絶対パス、トラバーサルシーケンス、シンボリックリンクはすべて受け入れられていました。
RTLD_NOW はすべてのシンボルを即座に解決し、dlopen が戻る 前 にオブジェクトの __attribute__((constructor)) / .init_array ルーチンを実行します。したがって、実行はロードの成功に依存せず、ペイロードが実行されるために TRITONBACKEND_ModelBatch* エントリポイントが存在する必要はありません。また、Triton プロセスの権限で実行されます(NGC コンテナではしばしば root)。
src/backend_model.cc — 攻撃者入力は batch_libpath に到達し、存在するかどうかのみが検証されます:
if (model_config.parameters().contains("TRITON_BATCH_STRATEGY_PATH")) {
batch_libpath = model_config.parameters()
.at("TRITON_BATCH_STRATEGY_PATH")
.string_value();
bool exists = false;
RETURN_IF_ERROR(FileExists(batch_libpath, &exists));
if (!exists) {
return Status(
triton::common::Error::Code::NOT_FOUND,
("Batching library path not found: " + batch_libpath).c_str());
}
}
注目すべきは、IsChildPathEscapingParentPath への呼び出しが存在しないことです。この関数は、同じファイル内の他の場所でラベルパスやバックエンドライブラリパスに既に適用されていました。
src/backend_model.cc — SetBatchingStrategy がそれを転送します:
Status TritonModel::SetBatchingStrategy(const std::string& batch_libpath)
{
std::unique_ptr<SharedLibrary> slib;
RETURN_IF_ERROR(SharedLibrary::Acquire(&slib));
RETURN_IF_ERROR(slib->OpenLibraryHandle(batch_libpath, &batch_dlhandle_));
src/shared_library.cc — シンク:
*handle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
model_config.parameters() を制御する現実的な経路は 3 つあります:
config.pbtxt を所有するテナントが、自分のディレクトリに .so を仕込み、パラメータをそこに向けます。ペイロードはサーバーの権限で実行され、他のすべてのテナントの重み、シークレット、GPU へのアクセスが得られます。file:<rel-path> パラメータプレフィックスと組み合わせた TRITONSERVER_ServerLoadModelWithParameters により、モデルロード権限を持つ呼び出し元は、単一のリクエストで config.pbtxt と .so を送信し、即座にロードをトリガーできます。API の外部でのファイルシステムアクセスは不要です。dlopen します。poc/ には、OpenLibraryHandle が行う処理に簡略化したプリミティブが含まれています。ソースのみです — 自分でビルドしてください:
$ cd poc && ./build.sh
$ gcc -O0 -o test_dlopen test_dlopen.c -ldl
$ ./test_dlopen ./evil.so
dlopen OK, handle=0x55d1779652c0
$ cat /tmp/triton_dlopen_rce_proof.log
[triton-dlopen-rce] constructor fired @ Fri May 1 09:56:56 2026
pid=240157 uid=1000 euid=1000 cwd=/opt/poc
このペイロードは無害です: pid、uid、euid、cwd を記録する 1 行を追記するだけです。Debian 13、GCC 14.2、x86_64 で検証済みです。
Triton 側のトリガーとしては、ビルドした evil.so をモデルリポジトリ内の poc/config.pbtxt の隣に置き、モデルをロードします — 自動ロード、--load-model、または POST /v2/repository/models/evil_model/load のいずれかです。影響を受けるバージョンでは、コンストラクタは SetBatchingStrategy の間に、バックエンドシンボルルックアップの前に起動します。
ロードは Triton 自身によって INFO でログに記録されます:
Loading custom batching strategy library <path> for model <name>
修正済みビルドでは、拒否された試みは Batching library path escapes model repository. として表示されます。
絶対パスである、.. を含む、またはモデルディレクトリの外に解決される TRITON_BATCH_STRATEGY_PATH 値は、バージョンに関係なく警告する価値があります。ログ行と設定パラメータの両方をカバーする Sigma ルールは detection/ にあります。
補完的なシグナル:
TRITON_BATCH_STRATEGY_PATH パラメータを持つ config.pbtxt ファイル自体 — この機能は実際にはまれなので、存在するだけで有用なフィルタになります。tritonserver プロセスによるモデルルート外の .so の openat/mmap(auditd、eBPF、または Falco を使用)。Triton Inference Server 26.06 以降にアップグレードしてください。 修正により、ローダーに欠けていた包含チェックが追加されます:
bool escapes{true};
RETURN_IF_ERROR(IsChildPathEscapingParentPath(
batch_libpath, localized_model_dir->Path(), &escapes));
if (escapes) {
return Status(
Status::Code::INVALID_ARG,
"Batching library path escapes model repository.");
}
アップグレードが直ちにできない場合の代替対策:
config.pbtxt から TRITON_BATCH_STRATEGY_PATH を拒否または削除します。explicit 以外の --model-control-mode、またはリポジトリエンドポイントでの認可)。tritonserver を非特権ユーザーとして、読み取り専用のモデルリポジトリマウントで実行し、ロードが成功した場合の影響範囲を可能な限り小さくします。関連付け: MITRE ATT&CK T1574.006 実行フローのハイジャック: 動的リンカーハイジャック および T1129 共有モジュール; NIST SP 800-53r5 SI-7、CM-5、SC-18; CIS Controls v8 §2、§4。
triton-inference-server/core — https://github.com/triton-inference-server/coreMIT — LICENSE を参照してください。
| CVE | CVE-2026-47630 |
| NVIDIA セキュリティ速報 | 5865 (2026-08-18) |
| CWE | CWE-36 (Absolute Path Traversal); reported as CWE-114 / CWE-829 |
| CVSS v3.1 (NVIDIA) | 5.5 MEDIUM — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| 影響を受けるバージョン | Triton Inference Server 0.0 – 26.05 (Linux) |
| 修正バージョン | 26.06 |
| 報告者 | s1ko (github.com/s1ko, [email protected]) |
| ベンダー追跡番号 | NVIDIA PSIRT ticket 6139742 |
| 日付 | イベント |
|---|
| 2026-04-25 | Triton のパス処理に関する最初の発見を報告。NVIDIA PSIRT がチケット 6128799 を開設 |
| 2026-05-01 | この二次的な発見が確認され報告。PSIRT がチケット 6139742 を開設 |
| 2026-05-28 | PSIRT と調整開示のペースについて合意 |
| 2026-06 | 修正が Triton Inference Server 26.06 に搭載 |
| 2026-08-18 | NVIDIA が速報 5865 を公開。CVE-2026-47630 を割り当て、s1ko への謝辞を記載 |
| 2026-08-22 | 本記事を公開 |