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.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

OpenCV FileStorage nd-matrix stack buffer overflow (CWE-787) PoC

A crafted OpenCV FileStorage JSON model/data file (poc.json) that triggers a stack-based buffer overflow with attacker-controlled write values in OpenCV's persistence parser, reached from a plain cv2.FileStorage(path, cv2.FILE_STORAGE_READ) read (and from any cv2.*::load / cv2.ml.*_load that deserializes a matrix member).

This repository is gated so the crafted file is not freely downloadable. Access has been granted to protectai-bot for huntr review.

Affected

  • opencv-python 4.13.0 (latest), verified on Linux x86_64 / Python 3.13.
  • The vulnerable code is unchanged on current OpenCV master.

Root cause

modules/core/src/persistence_types.cpp, read(const FileNode&, Mat&, const Mat&) (current master lines 129-134; identical twin in the SparseMat reader at 156-163):

int sizes[CV_MAX_DIM] = {0}, dims;        // CV_MAX_DIM == 32  ->  int sizes[32] on the stack
FileNode sizes_node = node["sizes"];
dims = (int)sizes_node.size();            // attacker-controlled count, NO upper bound
sizes_node.readRaw("i", sizes, dims*sizeof(sizes[0]));   // writes `dims` ints into the 32-int buffer
m.create(dims, sizes, elem_type);         // the CV_MAX_DIM check is inside create() -- runs too late

For a node with type_id opencv-nd-matrix, dims is taken straight from the number of entries in the file's "sizes" array, and readRaw then writes that many ints into the fixed 32-int stack buffer. There is no check that dims <= CV_MAX_DIM before the write. More than 32 entries overflows the buffer; the written values are the "sizes" entries themselves, so the attacker controls the bytes that land on the saved registers and return address.

Files

  • poc.json - the crafted file: an opencv-nd-matrix node whose "sizes" array has 200 entries, each 0x41414141.
  • make_poc.py - regenerates poc.json and documents the construction.
  • verify.py - offline, deterministic check. Loads the file in a child process and runs a differential (a benign 32-dim matrix loads; the 200-dim file crashes). Only needs opencv-python.

Reproduce

pip install opencv-python
python verify.py

Expected:

[benign 32-dim nd-matrix] exit=0   loaded: (1, 1, ... 32 ones ...)
[crafted poc.json]        exit=-11
RESULT: VULNERABLE - benign loads, crafted file crashes the parser (stack overflow)

Under a debugger the crafted file overwrites the saved return addresses with 0x4141414141414141 (the attacker-supplied "sizes" value), confirming the write is controlled rather than a blind DoS:

Thread 1 "python" received signal SIGSEGV, Segmentation fault.
#7  0x4141414141414141 in ?? ()
#8  0x4141414141414141 in ?? ()
...

Impact

Loading an untrusted OpenCV .json (or .xml/.yml) model/data file via FileStorage corrupts the stack with attacker-controlled bytes that reach the saved return address. At minimum this is a reliable native crash (denial of service) at load time; because the overwrite is attacker-controlled it is a memory-corruption primitive (CWE-787) whose ceiling is control-flow hijack, subject to the platform mitigations in effect.

Remediation

Validate dims against CV_MAX_DIM before the readRaw write in both read(FileNode, Mat&) and read(FileNode, SparseMat&), e.g. CV_Assert(0 <= dims && dims <= CV_MAX_DIM); immediately after dims = (int)sizes_node.size();.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support