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

Check out the documentation for more information.

MNN external-weight size mismatch β†’ heap OOB write (CWE-787)

Target: MNN (Alibaba, deployed at scale β€” Taobao/Alipay/numerous mobile & edge apps) Class: CWE-787 Out-of-bounds Write (heap), controlled size + controlled content Route: huntr / Protect AI β€” MFV (.mnn model-file parsing β†’ memory corruption)

Summary

MNN's external-weight loading for the Scale and LayerNorm ops allocates the second buffer (bias/beta) using externalInfo[1] (the first size field) but reads it using externalInfo[2] (an independent, file-controlled size field), with no externalInfo[2] <= externalInfo[1] check. A malicious .mnn model whose op carries external = [offset, 16, LARGE] makes FileLoader::read(biasData, LARGE) write LARGE attacker-controlled bytes into a 16-byte heap buffer β†’ controlled heap OOB write.

Root cause (master source/core/OpCommonUtils.cpp)

Scale case (:557-566):

int outputCount = externalInfo[1] / sizeof(float);   // from FIRST size
std::vector<float> scaleData(outputCount);
external->read((char*)scaleData.data(), externalInfo[1]);   // consistent
if (externalSize > 2) {
    std::vector<float> biasData(outputCount);               // sized by externalInfo[1]
    external->read((char*)biasData.data(), externalInfo[2]);// read by externalInfo[2] -> OOB
}

LayerNorm case (:580-585): identical pattern (gamma/beta). The code assumes bias size == scale size (same channel count) but reads the independent field unchecked.

PoC β€” real files, official MNN 3.6.0 pip wheel

file external field result
benign.mnn / benign.bin [0, 16, 16] loads cleanly via Interpreter.createSession (control)
malicious.mnn / malicious.bin [0, 16, 4194304] SIGSEGV in OpCommonUtils::createExecutionWithExternal during createSession
mid.mnn / mid.bin [0, 16, 4096] intermediate (also faults)

The benign and malicious models are byte-identical except the single external[2] size field (and the matching external weight blob length). Regenerate with gen_poc.py (uses flatc-generated MNN schema); load with load_poc.py (official pip install MNN 3.6.0 wheel β€” no custom/instrumented build).

Crash trace (official wheel, gdb)

Thread 1 received signal SIGSEGV, Segmentation fault.
#0 MNN::OpCommonUtils::createExecutionWithExternal(...)        <- fault
#1 MNN::Pipeline::allocMemory(bool, bool)
#2 MNN::Session::resize()
#3 MNN::Interpreter::createMultiPathSession(...)
#4 MNN::Interpreter::createMultiPathSession(...)
#5 MNN::Interpreter::createSession(...)
#6 PyMNNInterpreter_createSession  (public Python API)

(full trace: trace_gdb.txt)

Reachability

Loading an untrusted external-weight .mnn via the public Interpreter::createFromFile / createSession path reaches the OOB write β€” no special flags required. External-weight is MNN's standard mechanism for shipping large models; such models arrive via app bundles / downloads / OTA and are untrusted by design.

dedup

MNN has 0 published security advisories; the OOB issues in its tracker are app-crash bugs, not this external-weight alloc-by-[1]/read-by-[2] vector. Complementary extracted-ASan evidence (verbatim heap-buffer-overflow WRITE of size 1000 into a 16-byte region) is recorded in the accompanying research notes.

Suggested fix

Validate externalInfo[2] == externalInfo[1] (bias matches scale) β€” or more generally externalInfo[i+1] <= the destination buffer's allocated bytes β€” before each read, and reject the model with MNN_ERROR on mismatch.

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