Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protoparse: index out of range in validateEnum #271

Closed
bradleyjkemp opened this issue Aug 24, 2019 · 1 comment · Fixed by #272
Closed

protoparse: index out of range in validateEnum #271

bradleyjkemp opened this issue Aug 24, 2019 · 1 comment · Fixed by #272

Comments

@bradleyjkemp
Copy link

I've seen a couple of panics in my project (which uses dynamic to unmarshal unknown messages). And so have been working on some fuzzing harnesses to try and pin down a small reproducible example. I haven't found my issue yet but did find this index out of range panic in protoparse.

Would you be interested in me opening a PR with the basic fuzzing harnesses I've got?
A service like fuzzbuzz.io/fuzzit.dev might be interesting to add to this project to run fuzzing continuously (with a lot more processing power than my laptop...). They're offering free CPU for open source projects and I'd be happy to help integrate it if you want 🙂

Fuzz harness:

package fuzz

import (
	"bytes"
	"github.com/jhump/protoreflect/desc/protoparse"
	"io"
	"io/ioutil"
)

func FuzzParser(data []byte) int {
	files := bytes.Split(data, []byte("\n\n"))
	fileNum := 0

	parser := protoparse.Parser{
		Accessor: func(_ string) (closer io.ReadCloser, e error) {
			if fileNum >= len(files) {
				fileNum = 0
			}

			return ioutil.NopCloser(bytes.NewReader(files[fileNum])), nil
		},
	}

	_, err := parser.ParseFiles("foo")
	if err != nil {
		return 0
	}

	return 1
}

Crashing input:

syntax="proto3";enum o{C}

Stack trace:

panic: runtime error: index out of range

goroutine 1 [running]:
github.com/jhump/protoreflect/desc/protoparse.validateEnum.func1(0xc00010ec00, 0xc00014aa38)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1362 +0x6a
github.com/jhump/protoreflect/desc/protoparse.validateEnum(0xc0000713e0, 0xc00014aa01, 0x0, 0x0, 0xc00010ec00, 0xc000071440, 0xc0000b1a68)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1362 +0x177e
github.com/jhump/protoreflect/desc/protoparse.basicValidate(0xc0000713e0)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1169 +0x1f2
github.com/jhump/protoreflect/desc/protoparse.parseProto(0x1316269, 0x3, 0x1694308, 0xc000117a60, 0xc00000aca0, 0x1357901, 0xc000071320)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:625 +0x134
github.com/jhump/protoreflect/desc/protoparse.parseProtoFile.func1(0x1358200, 0xc000117a60, 0x1316269, 0x3, 0xc00000aca0, 0x1, 0xc0000b1b88)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:413 +0xe8
github.com/jhump/protoreflect/desc/protoparse.parseProtoFile(0xc0000712c0, 0x1316269, 0x3, 0x0, 0xc00000aca0, 0x101, 0xc0000b1d30)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:414 +0xb06
github.com/jhump/protoreflect/desc/protoparse.parseProtoFiles(0xc0000712c0, 0xc0000b1e60, 0x1, 0x1, 0xc00000aca0, 0x2220101, 0xc0000b1d30)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:392 +0xdb
github.com/jhump/protoreflect/desc/protoparse.Parser.ParseFiles(0x0, 0x0, 0x0, 0x0, 0xc0000712c0, 0x0, 0x0, 0xc0000b1e60, 0x1, 0x1, ...)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:190 +0x202
github.com/jhump/protoreflect/internal/fuzz.FuzzParser(0x2220000, 0x19, 0x200000, 0x4)
	$GOPATH/src/github.com/jhump/protoreflect/internal/fuzz/parser.go:24 +0x203
go-fuzz-dep.Main(0xc0000b1f80, 0x1, 0x1)
	/var/folders/6m/r713l1xj6_dcykbx21svs09h0000gp/T/go-fuzz-build860565645/goroot/src/go-fuzz-dep/main.go:36 +0x1b6
main.main()
	/var/folders/6m/r713l1xj6_dcykbx21svs09h0000gp/T/go-fuzz-build860565645/gopath/src/github.com/jhump/protoreflect/internal/fuzz/go.fuzz.main/main.go:15 +0x52
exit status 2
@bradleyjkemp
Copy link
Author

In case it helps debugging, here's a very similar input that also fails with a slightly different stack trace:

syntax="proto3";enum o{N=572}
panic: runtime error: index out of range

goroutine 1 [running]:
github.com/jhump/protoreflect/desc/protoparse.validateEnum.func4.1(0xc000427300, 0xffffffffffffffff)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1362 +0x9d
github.com/jhump/protoreflect/desc/protoparse.validateEnum.func4(0xc000427300, 0xc00043ce00)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1362 +0x43
github.com/jhump/protoreflect/desc/protoparse.validateEnum(0xc0001b87b0, 0x1431401, 0x0, 0x0, 0xc000427300, 0xc0001b8810, 0xc0000eb9f8)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1362 +0x1929
github.com/jhump/protoreflect/desc/protoparse.basicValidate(0xc0001b87b0)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:1169 +0x1d1
github.com/jhump/protoreflect/desc/protoparse.parseProto(0x13eb70e, 0x3, 0x1c24308, 0xc000235660, 0xc0003f57c0, 0x1430701, 0xc0001b86c0)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:625 +0x134
github.com/jhump/protoreflect/desc/protoparse.parseProtoFile.func1(0x1431000, 0xc000235660, 0x13eb70e, 0x3, 0xc0003f57c0, 0x1, 0xc0000ebb18)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:413 +0xe8
github.com/jhump/protoreflect/desc/protoparse.parseProtoFile(0xc0003f57a0, 0x13eb70e, 0x3, 0x0, 0xc0003f57c0, 0x101, 0xc0000ebcc0)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:414 +0xb06
github.com/jhump/protoreflect/desc/protoparse.parseProtoFiles(0xc0003f57a0, 0xc0000ebe50, 0x1, 0x1, 0xc0003f57c0, 0x1380101, 0xc0000ebcc0)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:392 +0xdb
github.com/jhump/protoreflect/desc/protoparse.Parser.ParseFiles(0x0, 0x0, 0x0, 0x0, 0xc0003f57a0, 0x0, 0x0, 0xc0000ebe50, 0x1, 0x1, ...)
	$GOPATH/src/github.com/jhump/protoreflect/desc/protoparse/parser.go:190 +0x239
github.com/jhump/protoreflect/internal/fuzz.FuzzDynamicUnmarshal(0x1c70000, 0x1d, 0x200000, 0x3)
	$GOPATH/src/github.com/jhump/protoreflect/internal/fuzz/dynamic_unmarshal.go:23 +0x238
go-fuzz-dep.Main(0xc0000ebf70, 0x3, 0x3)
	/var/folders/6m/r713l1xj6_dcykbx21svs09h0000gp/T/go-fuzz-build235813830/goroot/src/go-fuzz-dep/main.go:36 +0x1b6
main.main()
	/var/folders/6m/r713l1xj6_dcykbx21svs09h0000gp/T/go-fuzz-build235813830/gopath/src/github.com/jhump/protoreflect/internal/fuzz/go.fuzz.main/main.go:19 +0x72
exit status 2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant