Add tests to exercise intential malicious overflow.

This commit adds several tests which intentionally attempt to feed
malicious data to the various deserialize functions.
This commit is contained in:
Dave Collins 2013-10-24 23:36:15 -05:00
parent 5cc32bbfc7
commit d1edbf1f0b
3 changed files with 197 additions and 33 deletions

View File

@ -381,6 +381,74 @@ func TestBlockSerializeErrors(t *testing.T) {
}
}
// TestBlockOverflowErrors performs tests to ensure deserializing blocks which
// are intentionally crafted to use large values for the number of transactions
// are handled properly. This could otherwise potentially be used as an attack
// vector.
func TestBlockOverflowErrors(t *testing.T) {
// Use protocol version 70001 specifically here instead of the latest
// protocol version because the test data is using bytes encoded with
// that version.
pver := uint32(70001)
tests := []struct {
buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
err error // Expected error
}{
// Block that claims to have ~uint64(0) transactions.
{
[]byte{
0x01, 0x00, 0x00, 0x00, // Version 1
0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
0x61, 0xbc, 0x66, 0x49, // Timestamp
0xff, 0xff, 0x00, 0x1d, // Bits
0x01, 0xe3, 0x62, 0x99, // Nonce
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // TxnCount
}, pver, &btcwire.MessageError{},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from wire format.
var msg btcwire.MsgBlock
r := bytes.NewBuffer(test.buf)
err := msg.BtcDecode(r, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
// Deserialize from wire format.
r = bytes.NewBuffer(test.buf)
err = msg.Deserialize(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
// Deserialize with transaction location info from wire format.
r = bytes.NewBuffer(test.buf)
_, err = msg.DeserializeTxLoc(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("DeserializeTxLoc #%d wrong error got: %v, "+
"want: %v", i, err, reflect.TypeOf(test.err))
continue
}
}
}
var blockOne = btcwire.MsgBlock{
Header: btcwire.BlockHeader{
Version: 1,

View File

@ -491,6 +491,102 @@ func TestTxSerializeErrors(t *testing.T) {
}
}
// TestTxOverflowErrors performs tests to ensure deserializing transactions
// which are intentionally crafted to use large values for the variable number
// of inputs and outputs are handled properly. This could otherwise potentially
// be used as an attack vector.
func TestTxOverflowErrors(t *testing.T) {
// Use protocol version 70001 and transaction version 1 specifically
// here instead of the latest values because the test data is using
// bytes encoded with those versions.
pver := uint32(70001)
txVer := uint32(1)
tests := []struct {
buf []byte // Wire encoding
pver uint32 // Protocol version for wire encoding
version uint32 // Transaction version
err error // Expected error
}{
// Transaction that claims to have ~uint64(0) inputs.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for number of input transactions
}, pver, txVer, &btcwire.MessageError{},
},
// Transaction that claims to have ~uint64(0) outputs.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0x00, // Varint for number of input transactions
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for number of output transactions
}, pver, txVer, &btcwire.MessageError{},
},
// Transaction that has an input with a signature script that
// claims to have ~uint64(0) length.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for length of signature script
}, pver, txVer, &btcwire.MessageError{},
},
// Transaction that has an output with a public key script
// that claims to have ~uint64(0) length.
{
[]byte{
0x00, 0x00, 0x00, 0x01, // Version
0x01, // Varint for number of input transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
0xff, 0xff, 0xff, 0xff, // Prevous output index
0x00, // Varint for length of signature script
0xff, 0xff, 0xff, 0xff, // Sequence
0x01, // Varint for number of output transactions
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Transaction amount
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, // Varint for length of public key script
}, pver, txVer, &btcwire.MessageError{},
},
}
t.Logf("Running %d tests", len(tests))
for i, test := range tests {
// Decode from wire format.
var msg btcwire.MsgTx
r := bytes.NewBuffer(test.buf)
err := msg.BtcDecode(r, test.pver)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
// Decode from wire format.
r = bytes.NewBuffer(test.buf)
err = msg.Deserialize(r)
if reflect.TypeOf(err) != reflect.TypeOf(test.err) {
t.Errorf("Deserialize #%d wrong error got: %v, want: %v",
i, err, reflect.TypeOf(test.err))
continue
}
}
}
// multiTx is a MsgTx with an input and output and used in various tests.
var multiTx = &btcwire.MsgTx{
Version: 1,

View File

@ -1,7 +1,7 @@
github.com/conformal/btcwire/message.go ReadMessage 100.00% (37/37)
github.com/conformal/btcwire/msgtx.go MsgTx.BtcDecode 100.00% (33/33)
github.com/conformal/btcwire/message.go WriteMessage 100.00% (31/31)
github.com/conformal/btcwire/msgtx.go MsgTx.BtcDecode 100.00% (27/27)
github.com/conformal/btcwire/msgversion.go MsgVersion.BtcDecode 100.00% (25/25)
github.com/conformal/btcwire/common.go readVarInt 100.00% (24/24)
github.com/conformal/btcwire/msgtx.go MsgTx.Copy 100.00% (24/24)
@ -9,62 +9,62 @@ github.com/conformal/btcwire/msgtx.go MsgTx.BtcEncode 100.00% (23/23)
github.com/conformal/btcwire/msgversion.go MsgVersion.BtcEncode 100.00% (22/22)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcDecode 100.00% (20/20)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.BtcDecode 100.00% (20/20)
github.com/conformal/btcwire/message.go makeEmptyMessage 100.00% (20/20)
github.com/conformal/btcwire/msgtx.go readTxIn 100.00% (20/20)
github.com/conformal/btcwire/netaddress.go readNetAddress 100.00% (20/20)
github.com/conformal/btcwire/message.go makeEmptyMessage 100.00% (20/20)
github.com/conformal/btcwire/msgblock.go MsgBlock.DeserializeTxLoc 100.00% (19/19)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.BtcEncode 100.00% (18/18)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.BtcEncode 100.00% (18/18)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcDecode 100.00% (17/17)
github.com/conformal/btcwire/msgtx.go readTxIn 100.00% (17/17)
github.com/conformal/btcwire/common.go writeVarInt 100.00% (16/16)
github.com/conformal/btcwire/msgblock.go MsgBlock.DeserializeTxLoc 100.00% (16/16)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcEncode 100.00% (15/15)
github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcEncode 100.00% (15/15)
github.com/conformal/btcwire/msgtx.go writeTxIn 100.00% (15/15)
github.com/conformal/btcwire/shahash.go NewShaHashFromStr 100.00% (15/15)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.BtcEncode 100.00% (15/15)
github.com/conformal/btcwire/msgblock.go MsgBlock.BtcDecode 100.00% (15/15)
github.com/conformal/btcwire/msgtx.go writeTxIn 100.00% (15/15)
github.com/conformal/btcwire/msgtx.go readTxOut 100.00% (15/15)
github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcDecode 100.00% (14/14)
github.com/conformal/btcwire/msginv.go MsgInv.BtcDecode 100.00% (14/14)
github.com/conformal/btcwire/netaddress.go writeNetAddress 100.00% (14/14)
github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcDecode 100.00% (14/14)
github.com/conformal/btcwire/msginv.go MsgInv.BtcDecode 100.00% (14/14)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.BtcDecode 100.00% (14/14)
github.com/conformal/btcwire/msgaddr.go MsgAddr.BtcDecode 100.00% (14/14)
github.com/conformal/btcwire/msgtx.go readTxOut 100.00% (12/12)
github.com/conformal/btcwire/msginv.go MsgInv.BtcEncode 100.00% (12/12)
github.com/conformal/btcwire/protocol.go ServiceFlag.String 100.00% (12/12)
github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcEncode 100.00% (12/12)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.BtcEncode 100.00% (12/12)
github.com/conformal/btcwire/msggetdata.go MsgGetData.BtcEncode 100.00% (12/12)
github.com/conformal/btcwire/protocol.go ServiceFlag.String 100.00% (12/12)
github.com/conformal/btcwire/msgtx.go writeTxOut 100.00% (11/11)
github.com/conformal/btcwire/msgblock.go MsgBlock.BtcDecode 100.00% (11/11)
github.com/conformal/btcwire/blockheader.go readBlockHeader 100.00% (10/10)
github.com/conformal/btcwire/common.go readVarString 100.00% (11/11)
github.com/conformal/btcwire/message.go discardInput 100.00% (10/10)
github.com/conformal/btcwire/blockheader.go readBlockHeader 100.00% (10/10)
github.com/conformal/btcwire/msgblock.go MsgBlock.BtcEncode 100.00% (9/9)
github.com/conformal/btcwire/blockheader.go writeBlockHeader 100.00% (8/8)
github.com/conformal/btcwire/msgalert.go MsgAlert.BtcDecode 100.00% (8/8)
github.com/conformal/btcwire/msgalert.go MsgAlert.BtcEncode 100.00% (8/8)
github.com/conformal/btcwire/common.go readVarString 100.00% (8/8)
github.com/conformal/btcwire/common.go writeVarString 100.00% (7/7)
github.com/conformal/btcwire/msgpong.go MsgPong.BtcEncode 100.00% (7/7)
github.com/conformal/btcwire/msgversion.go NewMsgVersionFromConn 100.00% (7/7)
github.com/conformal/btcwire/msgalert.go MsgAlert.BtcDecode 100.00% (8/8)
github.com/conformal/btcwire/blockheader.go writeBlockHeader 100.00% (8/8)
github.com/conformal/btcwire/common.go randomUint64 100.00% (7/7)
github.com/conformal/btcwire/msgpong.go MsgPong.BtcEncode 100.00% (7/7)
github.com/conformal/btcwire/msgpong.go MsgPong.BtcDecode 100.00% (7/7)
github.com/conformal/btcwire/message.go readMessageHeader 100.00% (7/7)
github.com/conformal/btcwire/common.go DoubleSha256 100.00% (7/7)
github.com/conformal/btcwire/msgtx.go MsgTx.TxSha 100.00% (5/5)
github.com/conformal/btcwire/netaddress.go NewNetAddress 100.00% (5/5)
github.com/conformal/btcwire/blockheader.go BlockHeader.BlockSha 100.00% (5/5)
github.com/conformal/btcwire/common.go writeElements 100.00% (5/5)
github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddress 100.00% (5/5)
github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddresses 100.00% (5/5)
github.com/conformal/btcwire/common.go readElements 100.00% (5/5)
github.com/conformal/btcwire/shahash.go ShaHash.SetBytes 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcEncode 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcDecode 100.00% (5/5)
github.com/conformal/btcwire/msgblock.go MsgBlock.TxShas 100.00% (5/5)
github.com/conformal/btcwire/msgversion.go NewMsgVersionFromConn 100.00% (7/7)
github.com/conformal/btcwire/common.go writeVarString 100.00% (7/7)
github.com/conformal/btcwire/common.go DoubleSha256 100.00% (6/6)
github.com/conformal/btcwire/msgnotfound.go MsgNotFound.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddresses 100.00% (5/5)
github.com/conformal/btcwire/msginv.go MsgInv.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/msgaddr.go MsgAddr.AddAddress 100.00% (5/5)
github.com/conformal/btcwire/msggetblocks.go MsgGetBlocks.AddBlockLocatorHash 100.00% (5/5)
github.com/conformal/btcwire/msggetheaders.go MsgGetHeaders.AddBlockLocatorHash 100.00% (5/5)
github.com/conformal/btcwire/shahash.go NewShaHash 100.00% (5/5)
github.com/conformal/btcwire/msgheaders.go MsgHeaders.AddBlockHeader 100.00% (5/5)
github.com/conformal/btcwire/msggetdata.go MsgGetData.AddInvVect 100.00% (5/5)
github.com/conformal/btcwire/shahash.go NewShaHash 100.00% (5/5)
github.com/conformal/btcwire/blockheader.go BlockHeader.BlockSha 100.00% (5/5)
github.com/conformal/btcwire/msgtx.go MsgTx.TxSha 100.00% (5/5)
github.com/conformal/btcwire/shahash.go ShaHash.SetBytes 100.00% (5/5)
github.com/conformal/btcwire/common.go readElements 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcEncode 100.00% (5/5)
github.com/conformal/btcwire/msgping.go MsgPing.BtcDecode 100.00% (5/5)
github.com/conformal/btcwire/common.go writeElements 100.00% (5/5)
github.com/conformal/btcwire/msgblock.go MsgBlock.TxShas 100.00% (5/5)
github.com/conformal/btcwire/netaddress.go NewNetAddress 100.00% (5/5)
github.com/conformal/btcwire/invvect.go readInvVect 100.00% (4/4)
github.com/conformal/btcwire/invvect.go writeInvVect 100.00% (4/4)
github.com/conformal/btcwire/msgmempool.go MsgMemPool.BtcDecode 100.00% (4/4)
@ -154,5 +154,5 @@ github.com/conformal/btcwire/msggetaddr.go MsgGetAddr.BtcEncode 100.00% (1/1
github.com/conformal/btcwire/msginv.go MsgInv.Command 100.00% (1/1)
github.com/conformal/btcwire/msginv.go MsgInv.MaxPayloadLength 100.00% (1/1)
github.com/conformal/btcwire/msginv.go NewMsgInv 100.00% (1/1)
github.com/conformal/btcwire --------------------------------- 100.00% (943/943)
github.com/conformal/btcwire --------------------------------- 100.00% (964/964)