# Unchecked pointer and limb arithmetic

Pointer or limb arithmetic used without wrap or modulus bound before the result is trusted

_Area: Memory corruption and native code. Seen in 3 disclosed reports; latest 2026-02-18. Updated 2026-10-23._

## How it works
Arithmetic on a pointer or on the limbs of a big number is assumed to stay in range, but nothing enforces that. A bump allocator adds a size to a position; a circuit assembles a value from limbs; a range check validates each piece. In each case the guard constrains one thing (the jump size, a per-limb bitlength, a byte width) while the actual danger is the wrap or the assembled total. When the sum wraps or exceeds the modulus, the computed pointer or value lands somewhere the guard never considered, and the code trusts it.

## Where it shows up
- Pointer increment (`pos += bytes`) with a range check on the delta but not on the wrap [E1](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.13.md).
- Limb-by-limb assembly where only per-limb bounds are checked, not the top limb against the remaining bit budget [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.2.2.md).
- Hint/advice functions that compute limbs but never assert `value == high*2^k + low` [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md).
- Range checks that bound each piece but not the recomposed whole.

## How to review
Identify every arithmetic result that becomes a pointer or a constrained value. The invariant: the result must be provably within the valid range before use. For pointers, check the addition is overflow-checked (or the size is bounded so wrap is impossible), and that any range guard constrains the final address, not just the delta [E1](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.13.md). For limbs, confirm the top limb is constrained to the remaining bit budget so the assembled value cannot exceed the modulus [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.2.2.md), and that a recomposition/equality assertion ties hinted limbs back to the source value [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md). A hint's internal checks are not constraints.

## Variants seen
- Bump allocator pointer wrap bypassing a SYSTEM-area jump guard [E1](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.13.md).
- Range check binding limb bitlengths but not limbs to value, enabling invalid witnesses [E2](https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md).
- Per-limb byte check leaving the top limb unconstrained, so a 32-bit address overflows the field modulus [E3](https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.2.2.md).

## Impact and severity
E1 yields a pointer overlapping existing heap cells; E3 allows writes to attacker-selected addresses; E2 lets a malicious prover supply inconsistent witnesses. Severity is high because the corrupted pointer or value is trusted downstream. It worsens when the only guard checks a proxy quantity (delta, per-limb width) rather than the final result.

## Evidence
- E1: https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.1.13.md
- E2: https://bugbountylibrary.com/r/c4%3A2025-09-succinct%3AH-01.md
- E3: https://bugbountylibrary.com/r/cantina%3Aopenvm_january2025%3A3.2.2.md
