You need to agree to share your contact information to access this model
This repository is publicly accessible, but you have to accept the conditions to access its files and content.
This repository contains malicious model files that intentionally trigger a heap out-of-bounds write in AMD MIGraphX. They are provided solely for coordinated vulnerability disclosure and vendor/triager verification. Do not load them on a system you care about.
Log in or Sign Up to review the conditions and access this model content.
PoC β AMD MIGraphX: heap out-of-bounds WRITE with attacker-controlled length and contents from a TensorFlow .pb model file
Reporter: Cyfra Tech Solutions (Roman Arce BrΓ‘n)
Track: huntr Model File Vulnerability (MFV)
Model file format: TF Saved Model / TensorFlow GraphDef (.pb)
Project: ROCm/AMDMIGraphX @ 49f842b387482e0df49b1f7b1b2c3a67856fd9a2 (internal version 2.17.0)
Root cause: src/tf/tf_parser.cpp β get_data_vals() (CWE-787) + integer truncation at :473 (CWE-190)
These files are weaponised model files. Load them only in a disposable sandbox.
The bug in one paragraph
get_data_vals() sizes its destination buffer from the tensor's declared shape and
then copies the tensor's actual value list into it, with no comparison between the
two β despite the comment on line 213 promising exactly that check:
212: std::vector<T> data_vals(shape_size); // size from the DECLARED SHAPE
213: // check if shape has enough data values given existing fields
214: if(data.size() == 1) { std::fill(...); }
218: else
219: copy(data.begin(), data.end(), data_vals.begin()); // <-- OOB WRITE
Shape and value list are independent fields of the same attacker-supplied protobuf, so the attacker chooses the victim allocation size, the overflow length, and the exact 32-bit word written at every offset.
Why this is memory corruption, not a DoS
On a stock non-sanitizer Release build, n_vals = 2..6 past a 4-byte buffer print
parsed OK and exit 0 with no allocator complaint β while ASAN proves the same file
performs WRITE of size 4, 0 bytes after 4-byte region at tf_parser.cpp:219. That is
silent corruption, not a safe crash. In n = 7..18, parsed OK is printed before
the abort, i.e. the corrupted program object has already been returned to the caller.
With poc-tf-positional-control.pb (189 bytes) we overwrote a live pointer with
0x4141414141414141, overwrote the following glibc chunk's size field, and landed our
planted 0xDEADBEEF / 0xCAFEBABE at the exact word offsets we aimed for.
No RCE is claimed or demonstrated. This is a controlled heap-overflow primitive.
Files
| File | Bytes | What it does |
|---|---|---|
poc-tf-oob-write-min.pb |
88 | minimal ASAN witness β 8 words past a 4-byte buffer |
poc-tf-oob-write.pb |
400,066 | ~400 KB written past a 4-byte buffer, same sink |
poc-tf-oob-write-adjacent.pb |
317 | 64 words β lands in adjacent live heap on a non-ASAN build |
poc-tf-positional-control.pb |
189 | length + content + offset control (0xDEADBEEF at word 20) |
poc-tf-int-trunc.pb |
16,458 | dims=[65536,65536] β int truncation to 0 at tf_parser.cpp:473 |
sweep/n02.pb β¦ sweep/n40.pb |
64β221 | silent-corruption-vs-abort sweep (dims=[1], n_vals = 2..40) |
sweep/two_*.pb |
152β196 | node ordering as a heap-grooming lever (unaligned tcache chunk detected) |
sweep/vic_*.pb |
450β466 | victim-grooming attempts (negative result, documented honestly) |
gen_poc.py |
β | deterministic regeneration β protobuf only, no TensorFlow needed |
ASAN-witness.txt |
58 KB | 6 full AddressSanitizer / gdb witnesses |
Reproduce
git clone https://github.com/ROCm/AMDMIGraphX && cd AMDMIGraphX
git checkout 49f842b387482e0df49b1f7b1b2c3a67856fd9a2
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-fsanitize=address -g"
cmake --build build -j
./build/bin/migraphx-driver read poc-tf-oob-write-min.pb
# AddressSanitizer: heap-buffer-overflow WRITE of size 4
# 0 bytes after 4-byte region, get_data_vals at src/tf/tf_parser.cpp:219
# allocated at src/tf/tf_parser.cpp:212
Deterministic, 10/10 runs. Also reachable through migraphx::parse_tf
(src/tf/tf.cpp:70), the C API migraphx_parse_tf / migraphx_parse_tf_buffer
(src/api/api.cpp:2388, :2398), the Python API (src/py/migraphx_py.cpp:753), and the
ONNX Runtime MIGraphX execution provider.
Regenerating the PoCs
protoc --python_out=pygen -I AMDMIGraphX/src/tf \
graph.proto node_def.proto attr_value.proto tensor.proto tensor_shape.proto \
resource_handle.proto types.proto function.proto op_def.proto versions.proto
PYGEN=pygen python3 gen_poc.py
Disclosure
Coordinated disclosure via huntr (MFV track) first; AMD PSIRT / GitHub Private
Vulnerability Reporting afterwards, per the project's SECURITY.md. Not publicly
disclosed until the vendor timeline is agreed.
Credit: Cyfra Tech Solutions (Roman Arce BrΓ‘n).