core/vm: fix overflows in DATACOPY and DATALOAD opcodes

This commit is contained in:
Marius van der Wijden 2025-02-13 11:05:09 +01:00
parent b78b30717c
commit 545fcb144a

View file

@ -222,7 +222,7 @@ func opDataLoad(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
stackItem = scope.Stack.pop() stackItem = scope.Stack.pop()
offset, overflow = stackItem.Uint64WithOverflow() offset, overflow = stackItem.Uint64WithOverflow()
) )
if overflow { if overflow || offset > uint64(scope.Contract.Container.dataSize) {
stackItem.Clear() stackItem.Clear()
scope.Stack.push(&stackItem) scope.Stack.push(&stackItem)
} else { } else {
@ -253,13 +253,17 @@ func opDataSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([
// opDataCopy implements the DATACOPY opcode // opDataCopy implements the DATACOPY opcode
func opDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { func opDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
var ( var (
memOffset = scope.Stack.pop() memOffset = scope.Stack.pop()
offset = scope.Stack.pop() dataOffset = scope.Stack.pop()
size = scope.Stack.pop() size = scope.Stack.pop()
) )
// These values are checked for overflow during memory expansion calculation dataOffset64, overflow := dataOffset.Uint64WithOverflow()
// (the memorySize function on the opcode). if overflow || dataOffset64 > uint64(scope.Contract.Container.dataSize) {
data := scope.Contract.Container.getDataAt(offset.Uint64(), size.Uint64()) // Setting to dataSize makes this a zero byte read
dataOffset64 = uint64(scope.Contract.Container.dataSize)
}
// memOffset and size are checked for overflow during memory expansion calculation.
data := scope.Contract.Container.getDataAt(dataOffset64, size.Uint64())
scope.Memory.Set(memOffset.Uint64(), size.Uint64(), data) scope.Memory.Set(memOffset.Uint64(), size.Uint64(), data)
return nil, nil return nil, nil
} }