fix: x/tx/decode: fix (*Decoder).Decode crash with invalid length prefix (#16681)

This commit is contained in:
Emmanuel T Odeke 2023-06-26 06:13:10 -07:00 committed by GitHub
parent 00791140f1
commit 51e01819c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 0 deletions

View File

@ -31,6 +31,10 @@ Ref: https://keepachangelog.com/en/1.0.0/
## [Unreleased]
### Bug Fixes
* [#16681](https://github.com/cosmos/cosmos-sdk/pull/16681): catch and fix `(*Decoder).Decode` crash from invalid length prefix in Tx bytes
## v0.8.0
### Improvements

View File

@ -3,6 +3,7 @@ package decode_test
import (
"encoding/hex"
"fmt"
"strings"
"testing"
"github.com/cosmos/cosmos-proto/anyutil"
@ -118,3 +119,31 @@ func (d dummyAddressCodec) StringToBytes(text string) ([]byte, error) {
func (d dummyAddressCodec) BytesToString(bz []byte) (string, error) {
return hex.EncodeToString(bz), nil
}
func TestDecodeTxBodyPanic(t *testing.T) {
crashVector := []byte{
0x0a, 0x0a, 0x09, 0xe7, 0xbf, 0xba, 0xe6, 0x82, 0x9a, 0xe6, 0xaa, 0x30,
}
cdc := new(dummyAddressCodec)
signingCtx, err := signing.NewContext(signing.Options{
AddressCodec: cdc,
ValidatorAddressCodec: cdc,
})
if err != nil {
t.Fatal(err)
}
dec, err := decode.NewDecoder(decode.Options{
SigningContext: signingCtx,
})
if err != nil {
t.Fatal(err)
}
_, err = dec.Decode(crashVector)
if err == nil {
t.Fatal("expected a non-nil error")
}
if g, w := err.Error(), "could not consume length prefix"; !strings.Contains(g, w) {
t.Fatalf("error mismatch\n%s\ndoes not contain\n\t%q", g, w)
}
}

View File

@ -85,6 +85,15 @@ func RejectUnknownFields(bz []byte, desc protoreflect.MessageDescriptor, allowUn
// consume length prefix of nested message
_, o := protowire.ConsumeVarint(fieldBytes)
if o < 0 {
err = fmt.Errorf("could not consume length prefix fieldBytes for nested message: %v: %w",
fieldMessage, protowire.ParseError(o))
return hasUnknownNonCriticals, err
} else if o > len(fieldBytes) {
err = fmt.Errorf("length prefix > len(fieldBytes) for nested message: %v", fieldMessage)
return hasUnknownNonCriticals, err
}
fieldBytes = fieldBytes[o:]
var err error