Files
xermicusandClaude Opus 4.8 16c255bf18 Fix/ny unaligned store fmp oog (#566)
Bug found by @jubnzv:

`--newyork`: an unaligned `mstore` corrupting the free-memory-pointer
word let a later store through the corrupted pointer silently succeed
where EVM runs out of gas.

---------

Signed-off-by: xermicus <bigcyrill@hotmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 09:13:59 +02:00

25 lines
1.2 KiB
Plaintext

/// Soundness PoC (newyork FMP range proof): an unaligned `mstore` that overlaps
/// the free-memory-pointer word `[0x40, 0x60)` corrupts the pointer with
/// arbitrary bytes, yet newyork kept its `FMP < heap_size` range proof, so a
/// subsequent store through the corrupted pointer silently succeeded instead of
/// running out of gas as EVM does on the unbounded memory expansion.
///
/// `mstore(56, not(0))` covers `[0x38, 0x58)`, overwriting the FMP word
/// `[0x40, 0x60)` with `0xff...`. `mload(0x40)` then reads the corrupted (huge)
/// pointer, and `mstore(mload(0x40), 0x42)` expands memory unboundedly — EVM
/// (and the stock pipeline) run out of gas. The fix flags `fmp_could_be_unbounded`
/// when such an overlap store is *observed* by a later `mload(0x40)`, disabling
/// the range proof so the corrupted pointer traps.
object "FmpOverlapOogBug" {
code { datacopy(0, dataoffset("FmpOverlapOogBug_deployed"), datasize("FmpOverlapOogBug_deployed")) return(0, datasize("FmpOverlapOogBug_deployed")) }
object "FmpOverlapOogBug_deployed" {
code {
mstore(0x40, 0x80)
mstore(56, not(0))
mstore(mload(0x40), 0x42)
mstore(0, 0)
return(0, 32)
}
}
}