-
Notifications
You must be signed in to change notification settings - Fork 55
Description
Describe the bug
This library provides no protection against untrusted inputs.
It is trivial to write inputs that will cause a server to OOM or crash from another issue.
This makes it impossible to use this package unless you have full trust in the users uploading input.
In our minio server we are therefore forced to disable Parquet parsing in S3 Select, since the server may be running in an environment where the users are untrusted.
Adding limits and safety to this package would extend its usage a lot. I know from experience it can be hard and there are a lot of paths to cover, but usually fuzz tests can guide you.
I made a fuzz test to test basic functionality. Even without a seed corpus it crashes within a minute, and letting it run a bit longer runs the OS out of resources as well. Ideally I would like to specify limits in terms of memory usage so we can make reasonable assumptions of how much memory each Reader will take at max.
Unit test to reproduce
Pre 1.18 fuzz test:
func Fuzz(data []byte) int {
r, err := NewFileReader(bytes.NewReader(data))
if err != nil {
return 0
}
for {
_, err := r.NextRow()
if err != nil {
break
}
for _, col := range r.Columns() {
_ = col.Element()
}
}
return 1
}Build+execute with:
λ go-fuzz-build -o=fuzz-build.zip .
λ go-fuzz -timeout=60 -bin=fuzz-build.zip -workdir=testdata/fuzz -procs=16
This will start crashing within a minute.
Details
Example crash:
panic: runtime error: makeslice: cap out of range
goroutine 1 [running]:
github.com/fraugster/parquet-go/parquet.(*FileMetaData).ReadField4(0xc00036c140, {0xbcc0f0, 0xc000016168}, {0xbcf4c0, 0xc00036c1e0})
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/parquet/parquet.go:11882 +0xd1
github.com/fraugster/parquet-go/parquet.(*FileMetaData).Read(0xc00036c140, {0xbcc0f0, 0xc000016168}, {0xbcf4c0, 0xc00036c1e0})
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/parquet/parquet.go:11753 +0x64b
github.com/fraugster/parquet-go.readThrift({0xbcc0f0, 0xc000016168}, {0xbc80c0, 0xc00036c140}, {0xbc81a0, 0xc00035c0d8})
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/helpers.go:107 +0xe2
github.com/fraugster/parquet-go.ReadFileMetaDataWithContext({0xbcc0f0, 0xc000016168}, {0xbca2b0, 0xc000358150}, 0x80)
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/file_meta.go:68 +0x5e7
github.com/fraugster/parquet-go.ReadFileMetaData({0xbca2b0, 0xc000358150}, 0x1)
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/file_meta.go:18 +0x70
github.com/fraugster/parquet-go.NewFileReaderWithOptions({0xbca2b0, 0xc000358150}, {0xc0000bfe10, 0x1, 0x1})
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/file_reader.go:39 +0x173
github.com/fraugster/parquet-go.NewFileReader({0xbca2b0, 0xc000358150}, {0x0, 0x984993, 0x625ea3ea})
e:/gopath/pkg/mod/github.com/fraugster/parquet-go@v0.10.0/file_reader.go:127 +0xa9
github.com/minio/minio/internal/s3select/parquet.Fuzz({0x1c37f2c0000, 0x3b, 0x3b})
d:/minio/minio/internal/s3select/parquet/fuzz.go:19 +0xbf
go-fuzz-dep.Main({0xc0000bff60, 0x2, 0x938c05})
go-fuzz-dep/main.go:36 +0x15b
main.main()
github.com/minio/minio/internal/s3select/parquet/go.fuzz.main/main.go:17 +0x45
exit status 2
I am not looking for a solution for the specific crash, but rather the class of crashes that can be triggered with malicious user inputs.
parquet-go specific details
- What version are you using?
0.10.0
- Can this be reproduced in earlier versions?
Likely.