diff --git a/core/tx_list.go b/core/tx_list.go index 3d237f13c1..66d00bb3b2 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -49,10 +49,12 @@ func (h *nonceHeap) Push(x interface{}) { func (h *nonceHeap) Pop() interface{} { old := *h - n := len(old) - x := old[n-1] - *h = old[0 : n-1] - return x + if n := len(old); n > 0 { + x := old[n-1] + *h = old[0 : n-1] + return x + } + return nil } // txSortedMap is a nonce->transaction hash map with a heap based index to allow diff --git a/core/vm/contracts_lightclient.go b/core/vm/contracts_lightclient.go index 473d8221cf..240a767453 100644 --- a/core/vm/contracts_lightclient.go +++ b/core/vm/contracts_lightclient.go @@ -28,6 +28,11 @@ const ( // 32 bytes | | | func decodeTendermintHeaderValidationInput(input []byte) (*lightclient.ConsensusState, *lightclient.Header, error) { csLen := binary.BigEndian.Uint64(input[consensusStateLengthBytesLength-uint64TypeLength : consensusStateLengthBytesLength]) + + if consensusStateLengthBytesLength+csLen < consensusStateLengthBytesLength { + return nil, nil, fmt.Errorf("integer overflow, csLen: %d", csLen) + } + if uint64(len(input)) <= consensusStateLengthBytesLength+csLen { return nil, nil, fmt.Errorf("expected payload size %d, actual size: %d", consensusStateLengthBytesLength+csLen, len(input)) } diff --git a/core/vm/lightclient/types.go b/core/vm/lightclient/types.go index 93c6da070d..674085b701 100644 --- a/core/vm/lightclient/types.go +++ b/core/vm/lightclient/types.go @@ -270,8 +270,9 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { inputLength := uint64(len(input)) pos := uint64(0) - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+valueLengthBytesLength+appHashLength { - return nil, fmt.Errorf("input length should be no less than %d", storeNameLengthBytesLength+keyLengthBytesLength+valueLengthBytesLength+appHashLength) + fixedSize := storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + appHashLength + if inputLength <= fixedSize { + return nil, fmt.Errorf("input length should be no less than %d", fixedSize) } storeName := string(bytes.Trim(input[pos:pos+storeNameLengthBytesLength], "\x00")) pos += storeNameLengthBytesLength @@ -279,7 +280,8 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { keyLength := binary.BigEndian.Uint64(input[pos+keyLengthBytesLength-8 : pos+keyLengthBytesLength]) pos += keyLengthBytesLength - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+keyLength+valueLengthBytesLength { + fixedSize = storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + if inputLength <= fixedSize+keyLength || fixedSize+keyLength < fixedSize { return nil, fmt.Errorf("invalid input, keyLength %d is too long", keyLength) } key := input[pos : pos+keyLength] @@ -288,7 +290,10 @@ func DecodeKeyValueMerkleProof(input []byte) (*KeyValueMerkleProof, error) { valueLength := binary.BigEndian.Uint64(input[pos+valueLengthBytesLength-8 : pos+valueLengthBytesLength]) pos += valueLengthBytesLength - if inputLength <= storeNameLengthBytesLength+keyLengthBytesLength+keyLength+valueLengthBytesLength+valueLength+appHashLength { + fixedSize = storeNameLengthBytesLength + keyLengthBytesLength + valueLengthBytesLength + appHashLength + if inputLength <= fixedSize+keyLength+valueLength || + fixedSize+keyLength < fixedSize || + fixedSize+keyLength+valueLength < valueLength { return nil, fmt.Errorf("invalid input, valueLength %d is too long", valueLength) } value := input[pos : pos+valueLength]