--- license: apache-2.0 tags: - security-poc - not-a-model --- # OpenVINO IR reader — stack-exhaustion DoS PoC (`read_model`) **⚠️ This repo contains a malicious proof-of-concept model file for a security report. It is NOT a usable ML model. Do not load `userdata_50000.xml` on a machine you care about — it deliberately crashes the OpenVINO loader.** ## What it is Two malicious IR files, each triggering an **independent unbounded-recursion site** in the IR deserializer (same missing-depth-cap class). Both have **no `.bin`** (weights are not needed). - `userdata_50000.xml` (1.84 MB) — a `Parameter` whose `` nests `` **50 000 deep** → `set_custom_rt_info` recursion. - `nested_ti_10000.xml` (7.98 MB) — `TensorIterator` layers nested **10 000 deep** via `` → `parse_function` recursion. When OpenVINO parses either file, the deserializer recurses once per nesting level with **no depth limit**, exhausting the stack and crashing `read_model` with `SIGSEGV`. ## Reproduce (one line each) ```bash pip install openvino # tested on 2026.2.1 python -c "import openvino as ov; ov.Core().read_model('userdata_50000.xml')" # -> Segfault (8/8) python -c "import openvino as ov; ov.Core().read_model('nested_ti_10000.xml')" # -> Segfault (3/3) ``` Symbolized AddressSanitizer traces: `asan-stackoverflow-evidence.txt` (Site A), `asan-parse_function-evidence.txt` (Site B). ## Root cause Unbounded recursion in the IR deserializer, `src/core/xml_util/src/xml_deserialize_util.cpp`: - `set_custom_rt_info` (lines 134–153) — recurses per nested `` element. - `parse_function` (line 921; recursion at line 871) — recurses per nested subgraph body (`TensorIterator`/`Loop`/`If`), a second instance of the same missing-guard class. Symbolized AddressSanitizer trace (from-source Debug build, HEAD `ce20c09`): ``` ==ERROR: AddressSanitizer: stack-overflow #21 set_custom_rt_info src/core/xml_util/src/xml_deserialize_util.cpp:147 #22 set_custom_rt_info src/core/xml_util/src/xml_deserialize_util.cpp:147 ... (thousands of identical frames) ... ``` ## Regenerate the PoC `fe_recursion.py` → `gen_user_data(50000)` (the `.xml` here) and `gen_nested_ti(20000)` (the subgraph-body variant). ## Impact Availability DoS: any service that calls `read_model`/`compile_model` on an untrusted OpenVINO IR model can be crashed by one small (~1.8 MB) `.xml`. ## Fix Cap recursion depth (or use an explicit worklist) in `set_custom_rt_info` and `parse_function`; reject IR whose `rt_info`/subgraph nesting exceeds a sane bound.