
Technische Schwachstellenanalyse und Proof-of-Concept für CVE-2026-47630, ein beliebiges dlopen über TRITON_BATCH_STRATEGY_PATH im NVIDIA Triton Inference Server, das die Ausführung von nativem Code ermöglicht, mit Anleitung zur Erkennung und Abschwächung.
dlopen über TRITON_BATCH_STRATEGY_PATHAbsolutes Pfad-Traversal im benutzerdefinierten Batching-Strategy-Loader von
triton-inference-server/core. Ein Modellkonfigurationsparameter wird
unvalidiert an dlopen(RTLD_NOW | RTLD_LOCAL) übergeben, sodass jeder, der
Einfluss auf die config.pbtxt eines Modells nehmen kann, beim Laden des
Modells native Codeausführung im Triton-Serverprozess erlangt.
NVIDIAs Bestätigung in Bulletin 5865 lautet wörtlich: CVE-2026-47630: s1ko.
Triton akzeptiert einen pro-Modell-Parameter TRITON_BATCH_STRATEGY_PATH aus
der config.pbtxt des Modells. Bis einschließlich 26.05 wurde der Wert als
beliebiger Dateisystempfad behandelt und unverändert an dlopen übergeben.
Es gab keine Containment-Prüfung, keine Allowlist und keine Signatur- oder
Hash-Verifikation. Absolute Pfade, Traversal-Sequenzen und Symlinks wurden
alle akzeptiert.
RTLD_NOW löst jedes Symbol sofort auf und führt die
__attribute__((constructor))- / .init_array-Routinen des Objekts vor
der Rückkehr von dlopen aus. Die Ausführung ist daher unabhängig von einem
erfolgreichen Laden — keiner der TRITONBACKEND_ModelBatch*-Einstiegspunkte
muss existieren, damit der Payload läuft, und er läuft mit den Privilegien des
Triton-Prozesses (häufig root in NGC-Containern).
src/backend_model.cc — Angreifereingabe erreicht batch_libpath, nur auf
Existenz validiert:
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());
}
}
Bemerkenswerterweise fehlt jeder Aufruf von IsChildPathEscapingParentPath,
das Triton an anderer Stelle in derselben Datei bereits auf Label-Pfade und
Backend-Bibliothekspfade anwendet.
src/backend_model.cc — SetBatchingStrategy reicht es weiter:
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 — die Senke:
*handle = dlopen(path.c_str(), RTLD_NOW | RTLD_LOCAL);
Drei praktische Wege, um model_config.parameters() zu kontrollieren:
config.pbtxt
seines Modells gehört, platziert eine .so in seinem eigenen Verzeichnis
und zeigt den Parameter darauf. Der Payload läuft mit den Privilegien des
Servers und ermöglicht Zugriff auf die Gewichte, Geheimnisse und GPUs
aller anderen Mandanten.TRITONSERVER_ServerLoadModelWithParameters in
Kombination mit dem dokumentierten Parameter-Präfix file:<rel-path>
erlaubt einem Aufrufer mit Modell-Ladeberechtigung, config.pbtxt und die
.so in einer einzigen Anfrage zu übermitteln und das Laden sofort
auszulösen. Es ist kein Dateisystemzugriff außerhalb der API erforderlich.dlopen aus.poc/ enthält die Primitive, reduziert auf das, was OpenLibraryHandle tut.
Nur Quellen — baut sie selbst:
$ 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
Der Payload ist inert: Er hängt eine Zeile an, die pid, uid, euid und cwd aufzeichnet. Verifiziert auf Debian 13, GCC 14.2, x86_64.
Für den Auslöser auf der Triton-Seite platziere die gebaute evil.so neben
poc/config.pbtxt im Modellrepository und lade das Modell
— per Auto-Load, --load-model oder
POST /v2/repository/models/evil_model/load. Auf einer betroffenen Version
feuert der Konstruktor während SetBatchingStrategy, vor jeder
Backend-Symbolsuche.
Das Laden wird von Triton selbst auf INFO protokolliert:
Loading custom batching strategy library <path> for model <name>
Bei einem korrigierten Build erscheint ein abgelehnter Versuch als
Batching library path escapes model repository.
Jeder TRITON_BATCH_STRATEGY_PATH-Wert, der absolut ist, .. enthält oder
außerhalb des Modellverzeichnisses aufgelöst wird, ist unabhängig von der
Version eine Alarmierung wert. Eine Sigma-Regel, die sowohl die Logzeile als
auch den Konfigurationsparameter abdeckt, befindet sich in
detection/.
Ergänzende Signale:
config.pbtxt-Dateien, die überhaupt einen TRITON_BATCH_STRATEGY_PATH-Parameter
enthalten — das Feature ist in der Praxis selten, daher ist allein das
Vorhandensein ein nützlicher Filter.openat/mmap einer .so außerhalb des Modell-Stammverzeichnisses durch
den tritonserver-Prozess (auditd, eBPF oder Falco).Upgrade auf Triton Inference Server 26.06 oder neuer. Der Fix fügt die Containment-Prüfung hinzu, die dem Loader fehlte:
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.");
}
Falls ein Upgrade nicht sofort möglich ist, gelten folgende kompensierende Kontrollen:
TRITON_BATCH_STRATEGY_PATH aus jeder config.pbtxt ab oder entferne
ihn, bevor sie das Modellrepository erreicht.--model-control-mode anders als
explicit oder Autorisierung an den Repository-Endpunkten), sofern er
nicht benötigt wird.tritonserver als unprivilegierten Benutzer mit einem
schreibgeschützten Mount des Modellrepositorys aus, sodass ein erfolgreiches
Laden einen möglichst kleinen Blast Radius hat.Zuordnung: MITRE ATT&CK
T1574.006 Hijack Execution Flow: Dynamic Linker Hijacking
und T1129 Shared Modules;
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 — siehe LICENSE.
| CVE | CVE-2026-47630 |
| NVIDIA-Bulletin | 5865 (2026-08-18) |
| CWE | CWE-36 (Absolute Path Traversal); gemeldet als 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 |
| Betroffen | Triton Inference Server 0.0 – 26.05 (Linux) |
| Behoben in | 26.06 |
| Gemeldet von | s1ko (github.com/s1ko, [email protected]) |
| Hersteller-Tracking | NVIDIA-PSIRT-Ticket 6139742 |
| Datum | Ereignis |
|---|
| 2026-04-25 | Primärer Befund zur Triton-Pfadbehandlung gemeldet; NVIDIA-PSIRT eröffnet Ticket 6128799 |
| 2026-05-01 | Dieser sekundäre Befund wurde bestätigt und gemeldet; PSIRT eröffnet Ticket 6139742 |
| 2026-05-28 | Takt für koordinierte Offenlegung mit PSIRT vereinbart |
| 2026-06 | Fix wird in Triton Inference Server 26.06 ausgeliefert |
| 2026-08-18 | NVIDIA veröffentlicht Bulletin 5865, weist CVE-2026-47630 zu und würdigt s1ko |
| 2026-08-22 | Dieser Bericht wurde veröffentlicht |