NamasteAlex's picture
Upload 3 files
e2dac80 verified
|
Raw
History Blame Contribute Delete
2.6 kB
metadata
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 <rt_info> nests <user_data> 50 000 deep β†’ set_custom_rt_info recursion.
  • nested_ti_10000.xml (7.98 MB) β€” TensorIterator layers nested 10 000 deep via <body> β†’ 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)

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 <user_data> 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.