jaminto's picture
Upload 2 files
e60ee36 verified
|
Raw
History Blame Contribute Delete
3.24 kB
---
license: other
tags:
- security
- bug-bounty
- proof-of-concept
- executorch
---
# ExecuTorch `.pte` β€” benign crash PoC (out-of-bounds read on `load_method`)
**This repository contains a benign proof-of-concept only. It causes a crash (SIGBUS,
out-of-bounds read) and does not execute attacker-controlled code, install a payload, or
perform any harmful action.** It exists to demonstrate a memory-safety vulnerability to
[Protect AI / huntr](https://huntr.com) as part of a coordinated disclosure.
## What this is
`poc_delegate_oob.pte` is a malformed ExecuTorch model file. When loaded by the standard
ExecuTorch C++ runtime under its **default** verification mode (`Verification::Minimal`),
it triggers an out-of-bounds read (SIGBUS) inside the XNNPACK backend delegate handoff.
Root cause: `Program::get_backend_delegate_data()` (`runtime/executor/program.cpp`) returns
the inline delegate blob's FlatBuffer-declared length **without validating it against the
real program buffer**, unlike the sibling `get_constant_buffer_data()`, which does bound
its size. A forged length field (~2 GiB, real blob ~30 bytes) is handed to the XNNPACK
backend as `(pointer, forged_size)`; `XNNCompiler::compileModel` then reads far outside the
mapped buffer and crashes.
## What it does NOT do
- No shellcode, no payload, no filesystem/network side effects.
- The only observable effect of loading this file is a process crash (SIGBUS).
## Reproduction
```python
from executorch.extension.pybindings import portable_lib as pl
data = open("poc_delegate_oob.pte", "rb").read()
prog = pl._load_program_from_buffer(data, program_verification=pl.Verification.Minimal)
for i in range(prog.num_methods()):
prog.load_method(prog.get_method_name(i)) # crashes with SIGBUS here
```
`poc_delegate_oob.py` is the script used to craft `poc_delegate_oob.pte` from a valid
`.pte` (`valid.pte`, included for reference) and to reproduce the crash under both the
default `Verification::Minimal` (crashes) and `Verification::InternalConsistency` (clean
error), confirming the FlatBuffer verifier is the missing guard.
### Fork-free reproduction (recommended)
`poc_delegate_oob.py`'s harness forks a child before loading, which is standard practice
for crash-testing but can invite a "is this just a fork/threading artifact?" question (Python
emits a benign `DeprecationWarning` about forking while multi-threaded β€” cosmetic, unrelated
to the crash). `standalone_crash.py` reproduces the identical crash with **no fork** β€” it
crafts the file and calls `load_method` directly in the main process:
```
python standalone_crash.py
# crashes immediately: Bus error (SIGBUS)
```
This is the same craft path and produces the same symbolicated backtrace
(`XNNCompiler::compileModel ← Method::init ← Program::load_method`) and the same fault
address (`Data Abort`, byte read, `== blob_base + attacker flatbuffer_offset`), confirming
the crash fires on the ordinary single-process load path a real embedding application uses.
## Disclosure status
Reported via huntr's Model File Vulnerability program (format: ExecuTorch / `.pte`).
This repo is gated β€” access requests are manually reviewed β€” per huntr's MFV PoC
submission requirements.