Skip to content

Commit 49bf077

Browse files
authored
crypto/types: fix negative index accesses in CompactUnmarshal,GetIndex,SetIndex (#9196)
Fixes unchecked negative index access that'd cause panics, in CompactBitArray's: * CompactUnmarshal, which blindly used the result of binary.Uvarint * GetIndex * SetIndex Fixes #9164 Fixes #9165
1 parent 9f835e7 commit 49bf077

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

crypto/types/compact_bit_array.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (bA *CompactBitArray) GetIndex(i int) bool {
5454
if bA == nil {
5555
return false
5656
}
57-
if i >= bA.Count() {
57+
if i < 0 || i >= bA.Count() {
5858
return false
5959
}
6060

@@ -68,7 +68,7 @@ func (bA *CompactBitArray) SetIndex(i int, v bool) bool {
6868
return false
6969
}
7070

71-
if i >= bA.Count() {
71+
if i < 0 || i >= bA.Count() {
7272
return false
7373
}
7474

@@ -262,6 +262,9 @@ func CompactUnmarshal(bz []byte) (*CompactBitArray, error) {
262262
}
263263

264264
size, n := binary.Uvarint(bz)
265+
if n < 0 || n >= len(bz) {
266+
return nil, fmt.Errorf("compact bit array: n=%d is out of range of len(bz)=%d", n, len(bz))
267+
}
265268
bz = bz[n:]
266269

267270
if len(bz) != int(size+7)/8 {

crypto/types/compact_bit_array_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,17 @@ func TestCompactMarshalUnmarshal(t *testing.T) {
184184
}
185185
}
186186

187+
// Ensure that CompactUnmarshal does not blindly try to slice using
188+
// a negative/out of bounds index of size returned from binary.Uvarint.
189+
// See issue https://github.com/cosmos/cosmos-sdk/issues/9165
190+
func TestCompactMarshalUnmarshalReturnsErrorOnInvalidSize(t *testing.T) {
191+
malicious := []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x24, 0x28}
192+
cba, err := CompactUnmarshal(malicious)
193+
require.Error(t, err)
194+
require.Nil(t, cba)
195+
require.Contains(t, err.Error(), "n=-11 is out of range of len(bz)=13")
196+
}
197+
187198
func TestCompactBitArrayNumOfTrueBitsBefore(t *testing.T) {
188199
testCases := []struct {
189200
marshalledBA string
@@ -227,6 +238,15 @@ func TestCompactBitArrayGetSetIndex(t *testing.T) {
227238
val := (r.Int63() % 2) == 0
228239
bA.SetIndex(index, val)
229240
require.Equal(t, val, bA.GetIndex(index), "bA.SetIndex(%d, %v) failed on bit array: %s", index, val, copy)
241+
242+
// Ensure that passing in negative indices to .SetIndex and .GetIndex do not
243+
// panic. See issue https://github.com/cosmos/cosmos-sdk/issues/9164.
244+
// To intentionally use negative indices, We want only values that aren't 0.
245+
if index == 0 {
246+
continue
247+
}
248+
require.False(t, bA.SetIndex(-index, val))
249+
require.False(t, bA.GetIndex(-index))
230250
}
231251
}
232252
}

0 commit comments

Comments
 (0)