# Attacker can forge arbitrary read value from memory in case skip_if_legitimate_fat_ptr

In zkSync Era VM, out-of-bounds fat-pointer reads skip memory access and cleanup masking, letting an attacker forge arbitrary dst0 read values.

- Payout: Contest reward
- Severity: high
- Program: zkSync
- Credited: xuwinnie
- Disclosed: 2024-02-29
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2023-10-zksync-findings/issues/702
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AH-03
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:high tech:rust technique:source-review vuln:memory-corruption vuln:misconfiguration

**Target:** zkSync Era zkEVM circuit (fat pointer memory read logic)
**Root cause:** When offset >= length on a fat pointer, skip_if_legitimate_fat_ptr skips the memory read and bytes_to_cleanup_out_of_bounds is masked to zero, so neither the memory sponge enforces the value nor the cleanup mask zeroes it.
**Steps:**
1. Craft a fat pointer read where offset >= length so offset_is_beyond_the_slice and is_fat_ptr are both true.
2. skip_memory_access becomes true, so should_read_a_cell is false and the memory sponge is not enforced.
3. bytes_out_of_bound is masked to zero, so bytes_to_cleanup_out_of_bounds = 0 and uma_ptr_read_cleanup_mask does not mask selected_word.
4. should_set_panic is false, so apply_any is true and dst0_value is pushed unconstrained.
5. Attacker supplies arbitrary dst0_value instead of the required zero bytes.
**How found:** Code review of the fat-pointer read path: noticed the spec requires zero bytes when offset >= length, traced that skip_if_legitimate_fat_ptr skips the read and zeroes bytes_to_cleanup_out_of_bounds, then observed dst0_value is pushed without panic or masking.
**Exploitation:** Attacker constructs a VM execution trace with an out-of-bounds fat-pointer read; because the circuit neither reads memory nor masks the result, the prover accepts an arbitrary chosen read value, breaking memory soundness of the zkEVM.
**Insight:** In zkVM circuit reviews, check every 'skip' optimization against the invariant it bypasses: if a memory access is skipped, verify the output is still constrained (masked to zero or panicked), since skipping the sponge lookup removes the only soundness anchor.
