Skip to content

Commit 6196f52

Browse files
Add some decoding size limits
- Set limit on single column size - Set limit on total column size - Add varheader size limits Without limits we were potentially trying to do huge allocations. Fuzz tests caught these.
1 parent 0c1e919 commit 6196f52

File tree

7 files changed

+51
-21
lines changed

7 files changed

+51
-21
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
go test fuzz v1
2+
[]byte("STEF\x02\x00\x00\x00\x02\x00\x00\x009\x0f\xca\xca\xca\xca\xca\n@\x00\x00\x00\xec\xeb\rK\x8a\xb0\x00\x00\x80\x00\x00\x00\x00\x04\x04\xa6\x00\x00\xc0\x00\x80\x90\x020\x03\x03@\x020\x000\xcb\xe1\x8dѺ\xfd\xea\u008b\x01\xf9\x87\xba\x9a\xebDž\xaa\x95\x01")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
go test fuzz v1
2+
[]byte("STEF\x02\x00\x01\x00\x02\v(\xb5/\xfd\x04h\x10\x00\x00\x00\x00\x00\x1c\x1f\xe0\x00\x00\x0f\x04,\x80\xff\xff\xff\x00\x00\x00\x00\x00\x00\x80\x00\x00 \x00\xc0\xe3\xec\u0099\xf2\xe1\xa7\xe8\x1e")
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
go test fuzz v1
2+
[]byte("STEF\x0201\x00\xee\xee\xee\xee\xee0\xee\xee\xee\xee\xee\xee\xee\xee0")

go/pkg/basereader.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func (r *BaseReader) ReadFixedHeader() error {
5252
return err
5353
}
5454

55-
if contentSize < 2 || contentSize > HdrContentSizeLimit {
55+
if contentSize < 2 || contentSize > FixedHdrContentSizeLimit {
5656
return ErrInvalidHeader
5757
}
5858

@@ -85,7 +85,12 @@ func (r *BaseReader) ReadVarHeader(ownSchema schema.WireSchema) error {
8585
return err
8686
}
8787

88-
hdrBytes := make([]byte, r.FrameDecoder.RemainingSize())
88+
hdrSize := r.FrameDecoder.RemainingSize()
89+
if hdrSize > VarHdrContentSizeLimit {
90+
return ErrInvalidVarHeader
91+
}
92+
93+
hdrBytes := make([]byte, hdrSize)
8994
n, err := r.FrameDecoder.Read(hdrBytes)
9095
if err != nil {
9196
return err

go/pkg/errors.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
package pkg
22

3-
import "errors"
3+
var ErrMultimap = NewDecodeError("invalid multimap")
4+
var ErrMultimapCountLimit = NewDecodeError("too many elements in the multimap")
5+
var ErrInvalidRefNum = NewDecodeError("invalid refNum")
6+
var ErrInvalidOneOfType = NewDecodeError("invalid oneof type")
47

5-
var ErrMultimap = errors.New("invalid multimap")
6-
var ErrMultimapCountLimit = errors.New("too many elements in the multimap")
7-
var ErrInvalidRefNum = errors.New("invalid refNum")
8-
var ErrInvalidOneOfType = errors.New("invalid oneof type")
8+
var ErrInvalidHeader = NewDecodeError("invalid FixedHeader")
9+
var ErrInvalidHeaderSignature = NewDecodeError("invalid FixedHeader signature")
10+
var ErrInvalidFormatVersion = NewDecodeError("invalid format version in the FixedHeader")
11+
var ErrInvalidCompression = NewDecodeError("invalid compression method")
912

10-
var ErrInvalidHeader = errors.New("invalid FixedHeader")
11-
var ErrInvalidHeaderSignature = errors.New("invalid FixedHeader signature")
12-
var ErrInvalidFormatVersion = errors.New("invalid format version in the FixedHeader")
13-
var ErrInvalidCompression = errors.New("invalid compression method")
13+
var ErrInvalidVarHeader = NewDecodeError("invalid VarHeader")
14+
15+
var ErrColumnSizeLimitExceeded = NewDecodeError("column size limit exceeded")
16+
var ErrTotalColumnSizeLimitExceeded = NewDecodeError("total column size limit exceeded")
17+
18+
type DecodeError struct {
19+
msg string
20+
}
21+
22+
func (e *DecodeError) Error() string {
23+
return e.msg
24+
}
25+
26+
func NewDecodeError(msg string) error {
27+
return &DecodeError{msg: msg}
28+
}

go/pkg/limits.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,9 @@ package pkg
22

33
const MultimapElemCountLimit = 1024
44

5-
const HdrContentSizeLimit = 1 << 20
5+
const FixedHdrContentSizeLimit = 1 << 20
6+
const VarHdrContentSizeLimit = 1 << 20
7+
8+
const ColumnSizeLimit = 1 << 24
9+
10+
const TotalColumnSizeLimit = 1 << 26

go/pkg/recordbuf.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ func (s *ReadColumnSet) SubColumnLen() int {
158158
func (s *ReadColumnSet) ReadSizesFrom(buf *BitsReader) error {
159159
// Read data size
160160
dataSize := buf.ReadUvarintCompact()
161+
if dataSize > ColumnSizeLimit {
162+
return ErrColumnSizeLimitExceeded
163+
}
161164
s.column.data = EnsureLen(s.column.data, int(dataSize))
162165

163166
if dataSize == 0 {
@@ -191,18 +194,9 @@ func (s *ReadColumnSet) ReadDataFrom(buf ByteAndBlockReader) error {
191194
}
192195
}
193196

194-
//s.readIndex = 0
195-
196197
return nil
197198
}
198199

199-
func (s *ReadColumnSet) PrintSchema(indent int) {
200-
//fmt.Printf("%s%d\n", strings.Repeat("-", indent), len(s.subColumns))
201-
//for _, subColumn := range s.subColumns {
202-
// subColumn.PrintSchema(indent + 1)
203-
//}
204-
}
205-
206200
func (s *ReadColumnSet) ResetData() {
207201
s.column.data = nil
208202
for i := range s.subColumns {
@@ -221,6 +215,11 @@ func (s *ReadBufs) ReadFrom(buf ByteAndBlockReader) error {
221215
if err != nil {
222216
return err
223217
}
218+
219+
if bufSize > TotalColumnSizeLimit {
220+
return ErrTotalColumnSizeLimitExceeded
221+
}
222+
224223
s.tempBufBytes = EnsureLen(s.tempBufBytes, int(bufSize))
225224
if _, err := io.ReadFull(buf, s.tempBufBytes); err != nil {
226225
return err

0 commit comments

Comments
 (0)