aboutsummaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
authorZeke Lu <lvzecai@gmail.com>2022-09-13 18:05:53 +0000
committerGopher Robot <gobot@golang.org>2022-10-06 14:46:33 +0000
commit9dfadf911d2dcb093c3a37c79869bead0f9f6349 (patch)
tree6488801d1ef06ab51d41fc9aa42151d2bd9f6d81 /src/debug
parentaf668c689c66588f8adb9f5cd6db812706536338 (diff)
downloadgo-9dfadf911d2dcb093c3a37c79869bead0f9f6349.tar.xz
debug/buildinfo: correct a typo in calculating next align index
When it calculates the smallest n such that: n >= i && n % buildInfoAlign == 0 the expression should be (i+buildInfoAlign-1)&^(buildInfoAlign-1) instead of (i+buildInfoAlign-1)&^buildInfoAlign Fixes #54968. Change-Id: Ibb7bdf568a521545b2609acc85e2ab4e05da5dae GitHub-Last-Rev: 479ebc140af9809f0bea039e643cb95b4f857614 GitHub-Pull-Request: golang/go#54971 Reviewed-on: https://go-review.googlesource.com/c/go/+/429815 Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Bryan Mills <bcmills@google.com>
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/buildinfo/buildinfo.go2
-rw-r--r--src/debug/buildinfo/buildinfo_test.go70
2 files changed, 71 insertions, 1 deletions
diff --git a/src/debug/buildinfo/buildinfo.go b/src/debug/buildinfo/buildinfo.go
index ef77f28ce5..255e6d3d50 100644
--- a/src/debug/buildinfo/buildinfo.go
+++ b/src/debug/buildinfo/buildinfo.go
@@ -164,7 +164,7 @@ func readRawBuildInfo(r io.ReaderAt) (vers, mod string, err error) {
data = data[i:]
break
}
- data = data[(i+buildInfoAlign-1)&^buildInfoAlign:]
+ data = data[(i+buildInfoAlign-1)&^(buildInfoAlign-1):]
}
// Decode the blob.
diff --git a/src/debug/buildinfo/buildinfo_test.go b/src/debug/buildinfo/buildinfo_test.go
index a0a816be17..ae04b4cb1d 100644
--- a/src/debug/buildinfo/buildinfo_test.go
+++ b/src/debug/buildinfo/buildinfo_test.go
@@ -7,6 +7,8 @@ package buildinfo_test
import (
"bytes"
"debug/buildinfo"
+ "debug/pe"
+ "encoding/binary"
"flag"
"fmt"
"internal/testenv"
@@ -245,3 +247,71 @@ func TestReadFile(t *testing.T) {
})
}
}
+
+// TestIssue54968 is a regression test for golang.org/issue/54968.
+//
+// The cause of issue 54968 is when the first buildInfoMagic is invalid, it
+// enters an infinite loop.
+func TestIssue54968(t *testing.T) {
+ t.Parallel()
+
+ const (
+ paddingSize = 200
+ buildInfoAlign = 16
+ )
+ buildInfoMagic := []byte("\xff Go buildinf:")
+
+ // Construct a valid PE header.
+ var buf bytes.Buffer
+
+ buf.Write([]byte{'M', 'Z'})
+ buf.Write(bytes.Repeat([]byte{0}, 0x3c-2))
+ // At location 0x3c, the stub has the file offset to the PE signature.
+ binary.Write(&buf, binary.LittleEndian, int32(0x3c+4))
+
+ buf.Write([]byte{'P', 'E', 0, 0})
+
+ binary.Write(&buf, binary.LittleEndian, pe.FileHeader{NumberOfSections: 1})
+
+ sh := pe.SectionHeader32{
+ Name: [8]uint8{'t', 0},
+ SizeOfRawData: uint32(paddingSize + len(buildInfoMagic)),
+ PointerToRawData: uint32(buf.Len()),
+ }
+ sh.PointerToRawData = uint32(buf.Len() + binary.Size(sh))
+
+ binary.Write(&buf, binary.LittleEndian, sh)
+
+ start := buf.Len()
+ buf.Write(bytes.Repeat([]byte{0}, paddingSize+len(buildInfoMagic)))
+ data := buf.Bytes()
+
+ if _, err := pe.NewFile(bytes.NewReader(data)); err != nil {
+ t.Fatalf("need a valid PE header for the misaligned buildInfoMagic test: %s", err)
+ }
+
+ // Place buildInfoMagic after the header.
+ for i := 1; i < paddingSize-len(buildInfoMagic); i++ {
+ // Test only misaligned buildInfoMagic.
+ if i%buildInfoAlign == 0 {
+ continue
+ }
+
+ t.Run(fmt.Sprintf("start_at_%d", i), func(t *testing.T) {
+ d := data[:start]
+ // Construct intentionally-misaligned buildInfoMagic.
+ d = append(d, bytes.Repeat([]byte{0}, i)...)
+ d = append(d, buildInfoMagic...)
+ d = append(d, bytes.Repeat([]byte{0}, paddingSize-i)...)
+
+ _, err := buildinfo.Read(bytes.NewReader(d))
+
+ wantErr := "not a Go executable"
+ if err == nil {
+ t.Errorf("got error nil; want error containing %q", wantErr)
+ } else if errMsg := err.Error(); !strings.Contains(errMsg, wantErr) {
+ t.Errorf("got error %q; want error containing %q", errMsg, wantErr)
+ }
+ })
+ }
+}