Skip to content

Commit

Permalink
Fix CODECOPY corner cases
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov committed Oct 30, 2024
1 parent 7a4a895 commit 1629408
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 12 deletions.
36 changes: 28 additions & 8 deletions system-contracts/contracts/EvmEmulator.yul
Original file line number Diff line number Diff line change
Expand Up @@ -1606,15 +1606,25 @@ object "EvmEmulator" {
evmGasLeft := chargeGas(evmGasLeft, dynamicGas)

dstOffset := add(dstOffset, MEM_OFFSET())

checkOverflow(sourceOffset, BYTECODE_OFFSET())
sourceOffset := add(sourceOffset, BYTECODE_OFFSET())

checkOverflow(sourceOffset, len)
// Check bytecode overflow
if gt(add(sourceOffset, len), sub(MEM_LEN_OFFSET(), 1)) {
panic()
// Check bytecode out-of-bounds access
let truncatedLen := len
if gt(add(sourceOffset, len), MEM_LEN_OFFSET()) {
truncatedLen := sub(MEM_LEN_OFFSET(), sourceOffset) // truncate
if gt(truncatedLen, MEM_LEN_OFFSET()) { // if sourceOffset > MEM_LEN_OFFSET()
truncatedLen := 0
}
$llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds
}

$llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, len)
if truncatedLen {
$llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, truncatedLen)
}

ip := add(ip, 1)
}
case 0x3A { // OP_GASPRICE
Expand Down Expand Up @@ -4622,15 +4632,25 @@ object "EvmEmulator" {
evmGasLeft := chargeGas(evmGasLeft, dynamicGas)

dstOffset := add(dstOffset, MEM_OFFSET())

checkOverflow(sourceOffset, BYTECODE_OFFSET())
sourceOffset := add(sourceOffset, BYTECODE_OFFSET())

checkOverflow(sourceOffset, len)
// Check bytecode overflow
if gt(add(sourceOffset, len), sub(MEM_LEN_OFFSET(), 1)) {
panic()
// Check bytecode out-of-bounds access
let truncatedLen := len
if gt(add(sourceOffset, len), MEM_LEN_OFFSET()) {
truncatedLen := sub(MEM_LEN_OFFSET(), sourceOffset) // truncate
if gt(truncatedLen, MEM_LEN_OFFSET()) { // if sourceOffset > MEM_LEN_OFFSET()
truncatedLen := 0
}
$llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds
}

$llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, len)
if truncatedLen {
$llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, truncatedLen)
}

ip := add(ip, 1)
}
case 0x3A { // OP_GASPRICE
Expand Down
18 changes: 14 additions & 4 deletions system-contracts/evm-emulator/EvmEmulatorLoop.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -396,15 +396,25 @@ for { } true { } {
evmGasLeft := chargeGas(evmGasLeft, dynamicGas)

dstOffset := add(dstOffset, MEM_OFFSET())

checkOverflow(sourceOffset, BYTECODE_OFFSET())
sourceOffset := add(sourceOffset, BYTECODE_OFFSET())

checkOverflow(sourceOffset, len)
// Check bytecode overflow
if gt(add(sourceOffset, len), sub(MEM_LEN_OFFSET(), 1)) {
panic()
// Check bytecode out-of-bounds access
let truncatedLen := len
if gt(add(sourceOffset, len), MEM_LEN_OFFSET()) {
truncatedLen := sub(MEM_LEN_OFFSET(), sourceOffset) // truncate
if gt(truncatedLen, MEM_LEN_OFFSET()) { // if sourceOffset > MEM_LEN_OFFSET()
truncatedLen := 0
}
$llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds
}

$llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, len)
if truncatedLen {
$llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, truncatedLen)
}

ip := add(ip, 1)
}
case 0x3A { // OP_GASPRICE
Expand Down

0 comments on commit 1629408

Please sign in to comment.