jaminto's picture
Upload 2 files
e60ee36 verified
|
Raw
History Blame Contribute Delete
3.24 kB
metadata
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 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

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.