forked from TrueCloudLab/neoneo-go
Merge pull request #435 from nspcc-dev/fix/max_item_size
Restrict max item size on stack in CAT and PUSHDATA4, one more step towards #373.
This commit is contained in:
commit
d46d679f36
3 changed files with 32 additions and 2 deletions
|
@ -59,6 +59,9 @@ func (c *Context) Next() (Instruction, []byte, error) {
|
||||||
case PUSHDATA4:
|
case PUSHDATA4:
|
||||||
var n uint32
|
var n uint32
|
||||||
r.ReadLE(&n)
|
r.ReadLE(&n)
|
||||||
|
if n > MaxItemSize {
|
||||||
|
return instr, nil, errors.New("parameter is too big")
|
||||||
|
}
|
||||||
numtoread = int(n)
|
numtoread = int(n)
|
||||||
c.nextip += 4
|
c.nextip += 4
|
||||||
case JMP, JMPIF, JMPIFNOT, CALL:
|
case JMP, JMPIF, JMPIFNOT, CALL:
|
||||||
|
|
|
@ -28,6 +28,10 @@ var (
|
||||||
const (
|
const (
|
||||||
// MaxArraySize is the maximum array size allowed in the VM.
|
// MaxArraySize is the maximum array size allowed in the VM.
|
||||||
MaxArraySize = 1024
|
MaxArraySize = 1024
|
||||||
|
|
||||||
|
// MaxItemSize is the maximum item size allowed in the VM.
|
||||||
|
MaxItemSize = 1024 * 1024
|
||||||
|
|
||||||
maxSHLArg = 256
|
maxSHLArg = 256
|
||||||
minSHLArg = -256
|
minSHLArg = -256
|
||||||
)
|
)
|
||||||
|
@ -439,6 +443,9 @@ func (v *VM) execute(ctx *Context, op Instruction, parameter []byte) {
|
||||||
case CAT:
|
case CAT:
|
||||||
b := v.estack.Pop().Bytes()
|
b := v.estack.Pop().Bytes()
|
||||||
a := v.estack.Pop().Bytes()
|
a := v.estack.Pop().Bytes()
|
||||||
|
if l := len(a) + len(b); l > MaxItemSize {
|
||||||
|
panic(fmt.Sprintf("too big item: %d", l))
|
||||||
|
}
|
||||||
ab := append(a, b...)
|
ab := append(a, b...)
|
||||||
v.estack.PushVal(ab)
|
v.estack.PushVal(ab)
|
||||||
case SUBSTR:
|
case SUBSTR:
|
||||||
|
|
|
@ -2,6 +2,7 @@ package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
@ -175,6 +176,16 @@ func TestPushData4ShortN(t *testing.T) {
|
||||||
assert.Equal(t, true, vm.HasFailed())
|
assert.Equal(t, true, vm.HasFailed())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPushData4BigN(t *testing.T) {
|
||||||
|
prog := make([]byte, 1+4+MaxItemSize+1)
|
||||||
|
prog[0] = byte(PUSHDATA4)
|
||||||
|
binary.LittleEndian.PutUint32(prog[1:], MaxItemSize+1)
|
||||||
|
|
||||||
|
vm := load(prog)
|
||||||
|
vm.Run()
|
||||||
|
assert.Equal(t, true, vm.HasFailed())
|
||||||
|
}
|
||||||
|
|
||||||
func TestPushData4Good(t *testing.T) {
|
func TestPushData4Good(t *testing.T) {
|
||||||
prog := makeProgram(PUSHDATA4, 3, 0, 0, 0, 1, 2, 3)
|
prog := makeProgram(PUSHDATA4, 3, 0, 0, 0, 1, 2, 3)
|
||||||
vm := load(prog)
|
vm := load(prog)
|
||||||
|
@ -1413,6 +1424,15 @@ func TestCATBadOneArg(t *testing.T) {
|
||||||
assert.Equal(t, true, vm.HasFailed())
|
assert.Equal(t, true, vm.HasFailed())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCATBadBigItem(t *testing.T) {
|
||||||
|
prog := makeProgram(CAT)
|
||||||
|
vm := load(prog)
|
||||||
|
vm.estack.PushVal(make([]byte, MaxItemSize/2+1))
|
||||||
|
vm.estack.PushVal(make([]byte, MaxItemSize/2+1))
|
||||||
|
vm.Run()
|
||||||
|
assert.Equal(t, true, vm.HasFailed())
|
||||||
|
}
|
||||||
|
|
||||||
func TestCATGood(t *testing.T) {
|
func TestCATGood(t *testing.T) {
|
||||||
prog := makeProgram(CAT)
|
prog := makeProgram(CAT)
|
||||||
vm := load(prog)
|
vm := load(prog)
|
||||||
|
|
Loading…
Reference in a new issue