core/vm: fix RJUMPV jump analysis overflow

This commit is contained in:
Marius van der Wijden 2024-08-30 12:37:34 +02:00
parent a7953691df
commit f314ec0847
2 changed files with 7 additions and 7 deletions

View file

@ -132,13 +132,13 @@ func eofCodeBitmapInternal(code, bits bitvec) bitvec {
for pc := uint64(0); pc < uint64(len(code)); { for pc := uint64(0); pc < uint64(len(code)); {
var ( var (
op = OpCode(code[pc]) op = OpCode(code[pc])
numbits uint8 numbits uint16
) )
pc++ pc++
switch { switch {
case op >= PUSH1 && op <= PUSH32: case op >= PUSH1 && op <= PUSH32:
numbits = uint8(op - PUSH1 + 1) numbits = uint16(op - PUSH1 + 1)
case op == RJUMP || op == RJUMPI || op == CALLF || op == JUMPF || op == DATALOADN: case op == RJUMP || op == RJUMPI || op == CALLF || op == JUMPF || op == DATALOADN:
numbits = 2 numbits = 2
case op == RJUMPV: case op == RJUMPV:
@ -153,11 +153,11 @@ func eofCodeBitmapInternal(code, bits bitvec) bitvec {
// Count missing, no more bits to mark. // Count missing, no more bits to mark.
return bits return bits
} }
numbits = code[pc]*2 + 1 numbits = uint16(code[pc])*2 + 3
if pc+uint64(numbits) > end { if pc+uint64(numbits) > end {
// Jump table is truncated, mark as many bits // Jump table is truncated, mark as many bits
// as possible. // as possible.
numbits = uint8(end - pc) numbits = uint16(end - pc)
} }
case op == DUPN || op == SWAPN || op == EXCHANGE || op == EOFCREATE || op == RETURNCONTRACT: case op == DUPN || op == SWAPN || op == EXCHANGE || op == EOFCREATE || op == RETURNCONTRACT:
numbits = 1 numbits = 1

View file

@ -15,7 +15,7 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
var ( var (
stackBounds = make(map[int]*bounds) stackBounds = make(map[int]*bounds)
maxStackHeight = int(metadata[section].Input) maxStackHeight = int(metadata[section].Input)
debugging = true debugging = !true
) )
setBounds := func(pos, min, maxi int) *bounds { setBounds := func(pos, min, maxi int) *bounds {
@ -179,10 +179,10 @@ func validateControlFlow2(code []byte, section int, metadata []*FunctionMetadata
return 0, ErrInvalidBackwardJump return 0, ErrInvalidBackwardJump
} }
change := int(params.StackLimit) - jt[nextOP].maxStack + jt[nextOP].minStack change := int(params.StackLimit) - jt[nextOP].maxStack + jt[nextOP].minStack
if have, want := nextBounds.max+change, currentBounds.max; have != want { if have, want := nextBounds.max+change, currentBounds.max; have < want {
return 0, fmt.Errorf("%w want %d as max got %d at pos %d,", ErrInvalidBackwardJump, want, have, pos) return 0, fmt.Errorf("%w want %d as max got %d at pos %d,", ErrInvalidBackwardJump, want, have, pos)
} }
if have, want := nextBounds.min+change, currentBounds.min; have != want { if have, want := nextBounds.min+change, currentBounds.min; have < want {
return 0, fmt.Errorf("%w want %d as min got %d at pos %d,", ErrInvalidBackwardJump, want, have, pos) return 0, fmt.Errorf("%w want %d as min got %d at pos %d,", ErrInvalidBackwardJump, want, have, pos)
} }
if currentStackMax != nextBounds.max { if currentStackMax != nextBounds.max {