From: Nikola Jokic Date: Fri, 2 Dec 2022 16:42:48 +0000 (+0100) Subject: debug/buildinfo: check pointer size on buildinfo.Read X-Git-Tag: go1.20rc2~1^2~39 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=c6ad9dc9b523b710afa07d7c5bcb6fe9d21c308c;p=gostls13.git debug/buildinfo: check pointer size on buildinfo.Read Previous implementation has a check on pointer size but only if ptrSize is 4. but it does not check on ptrSize 8 causing the panic on read for some inputs. The explicit check for pointer size 8 is added and error is returned if ptrSize is not 4 and not 8. Fixes #57002 Change-Id: Id51de72bdef4da9955d086bfc2a5d735678ee2ac Reviewed-on: https://go-review.googlesource.com/c/go/+/454616 Auto-Submit: Bryan Mills TryBot-Result: Gopher Robot Run-TryBot: Bryan Mills Reviewed-by: Than McIntosh Reviewed-by: Bryan Mills --- diff --git a/src/debug/buildinfo/buildinfo.go b/src/debug/buildinfo/buildinfo.go index 255e6d3d50..8bc5753a2d 100644 --- a/src/debug/buildinfo/buildinfo.go +++ b/src/debug/buildinfo/buildinfo.go @@ -192,8 +192,10 @@ func readRawBuildInfo(r io.ReaderAt) (vers, mod string, err error) { var readPtr func([]byte) uint64 if ptrSize == 4 { readPtr = func(b []byte) uint64 { return uint64(bo.Uint32(b)) } - } else { + } else if ptrSize == 8 { readPtr = bo.Uint64 + } else { + return "", "", errNotGoExe } vers = readString(x, ptrSize, readPtr, readPtr(data[16:])) mod = readString(x, ptrSize, readPtr, readPtr(data[16+ptrSize:])) diff --git a/src/debug/buildinfo/buildinfo_test.go b/src/debug/buildinfo/buildinfo_test.go index ae04b4cb1d..290e3705bc 100644 --- a/src/debug/buildinfo/buildinfo_test.go +++ b/src/debug/buildinfo/buildinfo_test.go @@ -248,6 +248,18 @@ func TestReadFile(t *testing.T) { } } +// FuzzIssue57002 is a regression test for golang.org/issue/57002. +// +// The cause of issue 57002 is when pointerSize is not being checked, +// the read can panic with slice bounds out of range +func FuzzIssue57002(f *testing.F) { + // input from issue + f.Add([]byte{0x4d, 0x5a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x50, 0x45, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3f, 0x0, 0x20, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x9, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xef, 0x20, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x0, 0x2, 0x0, 0x20, 0x0, 0x0, 0x9, 0x0, 0x4, 0x0, 0x20, 0xf6, 0x0, 0xd3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa, 0x20, 0xa, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0x20, 0x47, 0x6f, 0x20, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x69, 0x6e, 0x66, 0x3a, 0xde, 0xb5, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x7f, 0x7f, 0x7f, 0x20, 0xf4, 0xb2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x5, 0x0, 0x20, 0x20, 0x20, 0x20, 0x0, 0x0, 0x0, 0x0, 0x20, 0x3f, 0x27, 0x20, 0x0, 0xd, 0x0, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0xff, 0x20, 0x20, 0xff, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0, 0x20, 0x20, 0x0, 0x0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20}) + f.Fuzz(func(t *testing.T, input []byte) { + buildinfo.Read(bytes.NewReader(input)) + }) +} + // TestIssue54968 is a regression test for golang.org/issue/54968. // // The cause of issue 54968 is when the first buildInfoMagic is invalid, it