mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-10-24 12:45:07 +00:00
Fix/ny dynamic calldatacopy fmp (#564)
Bug found by @jubnzv: `--newyork`: a `calldatacopy`/`codecopy`/`returndatacopy` to a dynamic destination that could overwrite the free-memory-pointer word truncated a subsequent `mload(0x40)` to `0`. --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Agent <agent@local>
This commit is contained in:
4 files changed
+191
-1
No files matched your search
@@ -4769,6 +4769,36 @@ fn array_bounds_probe() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Regression (newyork FMP range proof): a `calldatacopy` whose *dynamic*
|
||||
/// destination can land on the free-memory-pointer word `[0x40, 0x60)` corrupts
|
||||
/// the FMP, but only *static* copy destinations flagged `fmp_could_be_unbounded`.
|
||||
/// `calldatacopy(and(b, 0xFF), 0, 23)` (with `b`'s low byte `0x40`) overwrites the
|
||||
/// FMP; the subsequent `mload(0x40)` was truncated to `0` by the surviving range
|
||||
/// proof instead of returning the copied bytes (23 × 0x11 then 9 × 0x00). The fix
|
||||
/// flags a dynamic copy destination unless it is provably free-pointer-relative
|
||||
/// (`add(mload(0x40), k)`, `>= 0x80`). Compared newyork-PVM vs solc-EVM.
|
||||
#[test]
|
||||
fn calldatacopy_dynamic_dest_fmp_corruption() {
|
||||
let mut actions = instantiate_yul(
|
||||
"contracts/CalldatacopyFmpDynBug.yul",
|
||||
"CalldatacopyFmpDynBug",
|
||||
);
|
||||
// word0: source bytes (0x11); word1: `b` with low byte 0x40 (the copy destination).
|
||||
let mut data = vec![0x11u8; 32];
|
||||
let mut b = [0u8; 32];
|
||||
b[31] = 0x40;
|
||||
data.extend_from_slice(&b);
|
||||
actions.push(Call {
|
||||
origin: TestAddress::Alice,
|
||||
dest: TestAddress::Instantiated(0),
|
||||
value: 0,
|
||||
gas_limit: Some(GAS_LIMIT),
|
||||
storage_deposit_limit: None,
|
||||
data,
|
||||
});
|
||||
run_differential(actions);
|
||||
}
|
||||
|
||||
/// Regression (newyork dead-store elimination): a store read back by an
|
||||
/// intervening unaligned *overlapping* load must not be eliminated as dead.
|
||||
/// `mem_opt` marked a pending store read only on an exact-offset load, so
|
||||
|
||||
Reference in new issue
Block a user