out-of-bounds · git:20261017.3e577be · 2026-10-17 · sha256 0d4bcf884ebef4f6

out-of-bounds git:20261017.3e577beA

Immutable. This exact content never changes and is served at /api/v1/blob/0d4bcf884ebef4f6.

---
name: out-of-bounds
description: Classify out-of-bounds read evidence — BUFFER_ACCESS events with array_oob_read/heap_oob_read categories. Maps to CWE-125.
license: MIT
compatibility: opencode,claude code,DSH
metadata:
  cwe: CWE-125
  severity: HIGH
  domain: memory
---

## Out-of-Bounds Analysis (CWE-125)

### Evidence Pattern
An out-of-bounds candidate has:
- **BUFFER_ACCESS event** with category `array_oob_read` (fixed-size array read
  past its declared size) or `heap_oob_read` (loop bound past a
  `malloc`/`calloc` allocation)
- The subscript appears on the read side of an expression, e.g.
  `secret = arr[i];` or `sum += buf[i];`
- **out_of_bounds**: the access site (function and line)
- **buffer**: the array being read (`array: <name> (capacity: N elements)` when
  the declared size resolved)
- **index**: the access index expression
- **call_path**: the function is reachable from an entry point

### Hint Tokens (Verdict Basis)

| Token | Meaning | Your action |
|-------|---------|-------------|
| `buf@<name>` | the array being read | the object of the OOB read |
| `cap@N` | the array's declared size in elements | compare `idx@` against this |
| `idx@<expr>` | the access index expression | CONSTANT: the detector already proved it reaches past `cap@` (machine-proved, confirm) |

This type only carries detector-proved reads, so a constant `idx@` past `cap@`
settles the row from the Hint alone — no evidence-file open needed.

### Typical Example
```c
int arr[10];
for (int i = 0; i <= 10; i++) {   /* i == 10 is out of bounds */
    secret = arr[i];              /* read past the array */
}
```

### Classification Rules

| Condition | Classification |
|-----------|---------------|
| Constant index (or a constant-valued variable `int n = 12; arr[n]`) >= array size, or loop bound provably overruns size | **confirmed** |
| Access guarded by a bounds check covering the read | **false-positive** |
| `sizeof(arr)` usage (not an element access) | **false-positive** |

An index that cannot be proven out-of-bounds (`buf[i]` with an unknown `i`) is
**not emitted at all** — the detector only reports OOB it can prove (constant
index past a known size, or a loop bound that provably overruns it).

### Fix Suggestions
- Change the loop to `i < arr_size` or `i <= arr_size - 1`
- Check the index against the allocation size before dereferencing
- Use `snprintf`-style sized APIs when reading from formatted buffers

### Severity Matrix

`status` and `severity` are independent: `status` = evidence verdict
(confirmed/dismissed), `severity` = impact (low/medium/high/critical).
`metadata.severity` is the type default, not a ceiling. The verdict is binary (confirmed/dismissed); dismissed → `low`.

| Shape | Severity |
|-------|----------|
| Provable OOB read of adjacent memory (info disclosure) | HIGH |
| OOB read leaking a sensitive adjacent buffer (secrets / canary) | CRITICAL |