summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChee Yang Lee <chee.yang.lee@intel.com>2022-09-14 23:14:49 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2022-09-16 18:41:14 +0100
commit2fa8edea5a7842beaa77f6e0bc90e57230275967 (patch)
tree7b4f71f34d49691cbe33592ec440ef25c2570908
parente49990f01e52a33f041341a4d492aee3db2ebd0a (diff)
downloadpoky-2fa8edea5a7842beaa77f6e0bc90e57230275967.tar.gz
go: fix and ignore several CVEs
backport fixes: CVE-2021-27918 CVE-2021-36221 CVE-2021-39293 CVE-2021-41771 ignore: CVE-2022-29526 CVE-2022-30634 (From OE-Core rev: ddb09ccc3caebbd3cf643bb3bb3c198845050c69) Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com> Signed-off-by: Steve Sakoman <steve@sakoman.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/go/go-1.14.inc10
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2021-27918.patch191
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2021-36221.patch101
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2021-39293.patch79
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2021-41771.patch86
5 files changed, 467 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.14.inc b/meta/recipes-devtools/go/go-1.14.inc
index 1458a11b3f..af6345205e 100644
--- a/meta/recipes-devtools/go/go-1.14.inc
+++ b/meta/recipes-devtools/go/go-1.14.inc
@@ -32,6 +32,10 @@ SRC_URI += "\
32 file://CVE-2022-30635.patch \ 32 file://CVE-2022-30635.patch \
33 file://CVE-2022-32148.patch \ 33 file://CVE-2022-32148.patch \
34 file://CVE-2022-32189.patch \ 34 file://CVE-2022-32189.patch \
35 file://CVE-2021-27918.patch \
36 file://CVE-2021-36221.patch \
37 file://CVE-2021-39293.patch \
38 file://CVE-2021-41771.patch \
35" 39"
36 40
37SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch" 41SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
@@ -42,3 +46,9 @@ SRC_URI[main.sha256sum] = "7ed13b2209e54a451835997f78035530b331c5b6943cdcd68a3d8
42# https://github.com/golang/go/issues/30999#issuecomment-910470358 46# https://github.com/golang/go/issues/30999#issuecomment-910470358
43CVE_CHECK_WHITELIST += "CVE-2021-29923" 47CVE_CHECK_WHITELIST += "CVE-2021-29923"
44 48
49# this issue affected go1.15 onwards
50# https://security-tracker.debian.org/tracker/CVE-2022-29526
51CVE_CHECK_WHITELIST += "CVE-2022-29526"
52
53# Issue only on windows
54CVE_CHECK_WHITELIST += "CVE-2022-30634"
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2021-27918.patch b/meta/recipes-devtools/go/go-1.14/CVE-2021-27918.patch
new file mode 100644
index 0000000000..faa3f7f641
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2021-27918.patch
@@ -0,0 +1,191 @@
1From d0b79e3513a29628f3599dc8860666b6eed75372 Mon Sep 17 00:00:00 2001
2From: Katie Hockman <katie@golang.org>
3Date: Mon, 1 Mar 2021 09:54:00 -0500
4Subject: [PATCH] encoding/xml: prevent infinite loop while decoding
5
6This change properly handles a TokenReader which
7returns an EOF in the middle of an open XML
8element.
9
10Thanks to Sam Whited for reporting this.
11
12Fixes CVE-2021-27918
13Fixes #44913
14
15Change-Id: Id02a3f3def4a1b415fa2d9a8e3b373eb6cb0f433
16Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1004594
17Reviewed-by: Russ Cox <rsc@google.com>
18Reviewed-by: Roland Shoemaker <bracewell@google.com>
19Reviewed-by: Filippo Valsorda <valsorda@google.com>
20Reviewed-on: https://go-review.googlesource.com/c/go/+/300391
21Trust: Katie Hockman <katie@golang.org>
22Run-TryBot: Katie Hockman <katie@golang.org>
23TryBot-Result: Go Bot <gobot@golang.org>
24Reviewed-by: Alexander Rakoczy <alex@golang.org>
25Reviewed-by: Filippo Valsorda <filippo@golang.org>
26
27https://github.com/golang/go/commit/d0b79e3513a29628f3599dc8860666b6eed75372
28CVE: CVE-2021-27918
29Upstream-Status: Backport
30Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
31---
32 src/encoding/xml/xml.go | 19 ++++---
33 src/encoding/xml/xml_test.go | 104 +++++++++++++++++++++++++++--------
34 2 files changed, 92 insertions(+), 31 deletions(-)
35
36diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
37index adaf4daf198b9..6f9594d7ba7a3 100644
38--- a/src/encoding/xml/xml.go
39+++ b/src/encoding/xml/xml.go
40@@ -271,7 +271,7 @@ func NewTokenDecoder(t TokenReader) *Decoder {
41 // it will return an error.
42 //
43 // Token implements XML name spaces as described by
44-// https://www.w3.org/TR/REC-xml-names/. Each of the
45+// https://www.w3.org/TR/REC-xml-names/. Each of the
46 // Name structures contained in the Token has the Space
47 // set to the URL identifying its name space when known.
48 // If Token encounters an unrecognized name space prefix,
49@@ -285,16 +285,17 @@ func (d *Decoder) Token() (Token, error) {
50 if d.nextToken != nil {
51 t = d.nextToken
52 d.nextToken = nil
53- } else if t, err = d.rawToken(); err != nil {
54- switch {
55- case err == io.EOF && d.t != nil:
56- err = nil
57- case err == io.EOF && d.stk != nil && d.stk.kind != stkEOF:
58- err = d.syntaxError("unexpected EOF")
59+ } else {
60+ if t, err = d.rawToken(); t == nil && err != nil {
61+ if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
62+ err = d.syntaxError("unexpected EOF")
63+ }
64+ return nil, err
65 }
66- return t, err
67+ // We still have a token to process, so clear any
68+ // errors (e.g. EOF) and proceed.
69+ err = nil
70 }
71-
72 if !d.Strict {
73 if t1, ok := d.autoClose(t); ok {
74 d.nextToken = t
75diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
76index efddca43e9102..5672ebb375f0d 100644
77--- a/src/encoding/xml/xml_test.go
78+++ b/src/encoding/xml/xml_test.go
79@@ -33,30 +33,90 @@ func (t *toks) Token() (Token, error) {
80
81 func TestDecodeEOF(t *testing.T) {
82 start := StartElement{Name: Name{Local: "test"}}
83- t.Run("EarlyEOF", func(t *testing.T) {
84- d := NewTokenDecoder(&toks{earlyEOF: true, t: []Token{
85- start,
86- start.End(),
87- }})
88- err := d.Decode(&struct {
89- XMLName Name `xml:"test"`
90- }{})
91- if err != nil {
92- t.Error(err)
93+ tests := []struct {
94+ name string
95+ tokens []Token
96+ ok bool
97+ }{
98+ {
99+ name: "OK",
100+ tokens: []Token{
101+ start,
102+ start.End(),
103+ },
104+ ok: true,
105+ },
106+ {
107+ name: "Malformed",
108+ tokens: []Token{
109+ start,
110+ StartElement{Name: Name{Local: "bad"}},
111+ start.End(),
112+ },
113+ ok: false,
114+ },
115+ }
116+ for _, tc := range tests {
117+ for _, eof := range []bool{true, false} {
118+ name := fmt.Sprintf("%s/earlyEOF=%v", tc.name, eof)
119+ t.Run(name, func(t *testing.T) {
120+ d := NewTokenDecoder(&toks{
121+ earlyEOF: eof,
122+ t: tc.tokens,
123+ })
124+ err := d.Decode(&struct {
125+ XMLName Name `xml:"test"`
126+ }{})
127+ if tc.ok && err != nil {
128+ t.Fatalf("d.Decode: expected nil error, got %v", err)
129+ }
130+ if _, ok := err.(*SyntaxError); !tc.ok && !ok {
131+ t.Errorf("d.Decode: expected syntax error, got %v", err)
132+ }
133+ })
134 }
135- })
136- t.Run("LateEOF", func(t *testing.T) {
137- d := NewTokenDecoder(&toks{t: []Token{
138- start,
139- start.End(),
140- }})
141- err := d.Decode(&struct {
142- XMLName Name `xml:"test"`
143- }{})
144- if err != nil {
145- t.Error(err)
146+ }
147+}
148+
149+type toksNil struct {
150+ returnEOF bool
151+ t []Token
152+}
153+
154+func (t *toksNil) Token() (Token, error) {
155+ if len(t.t) == 0 {
156+ if !t.returnEOF {
157+ // Return nil, nil before returning an EOF. It's legal, but
158+ // discouraged.
159+ t.returnEOF = true
160+ return nil, nil
161 }
162- })
163+ return nil, io.EOF
164+ }
165+ var tok Token
166+ tok, t.t = t.t[0], t.t[1:]
167+ return tok, nil
168+}
169+
170+func TestDecodeNilToken(t *testing.T) {
171+ for _, strict := range []bool{true, false} {
172+ name := fmt.Sprintf("Strict=%v", strict)
173+ t.Run(name, func(t *testing.T) {
174+ start := StartElement{Name: Name{Local: "test"}}
175+ bad := StartElement{Name: Name{Local: "bad"}}
176+ d := NewTokenDecoder(&toksNil{
177+ // Malformed
178+ t: []Token{start, bad, start.End()},
179+ })
180+ d.Strict = strict
181+ err := d.Decode(&struct {
182+ XMLName Name `xml:"test"`
183+ }{})
184+ if _, ok := err.(*SyntaxError); !ok {
185+ t.Errorf("d.Decode: expected syntax error, got %v", err)
186+ }
187+ })
188+ }
189 }
190
191 const testInput = `
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2021-36221.patch b/meta/recipes-devtools/go/go-1.14/CVE-2021-36221.patch
new file mode 100644
index 0000000000..9c00d4ebb2
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2021-36221.patch
@@ -0,0 +1,101 @@
1From b7a85e0003cedb1b48a1fd3ae5b746ec6330102e Mon Sep 17 00:00:00 2001
2From: Damien Neil <dneil@google.com>
3Date: Wed, 7 Jul 2021 16:34:34 -0700
4Subject: [PATCH] net/http/httputil: close incoming ReverseProxy request body
5
6Reading from an incoming request body after the request handler aborts
7with a panic can cause a panic, becuse http.Server does not (contrary
8to its documentation) close the request body in this case.
9
10Always close the incoming request body in ReverseProxy.ServeHTTP to
11ensure that any in-flight outgoing requests using the body do not
12read from it.
13
14Updates #46866
15Fixes CVE-2021-36221
16
17Change-Id: I310df269200ad8732c5d9f1a2b00de68725831df
18Reviewed-on: https://go-review.googlesource.com/c/go/+/333191
19Trust: Damien Neil <dneil@google.com>
20Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
21Reviewed-by: Filippo Valsorda <filippo@golang.org>
22
23https://github.com/golang/go/commit/b7a85e0003cedb1b48a1fd3ae5b746ec6330102e
24CVE: CVE-2021-36221
25Upstream-Status: Backport
26Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
27---
28 src/net/http/httputil/reverseproxy.go | 9 +++++
29 src/net/http/httputil/reverseproxy_test.go | 39 ++++++++++++++++++++++
30 2 files changed, 48 insertions(+)
31
32diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
33index 5d39955d62d15..8b63368386f43 100644
34--- a/src/net/http/httputil/reverseproxy.go
35+++ b/src/net/http/httputil/reverseproxy.go
36@@ -235,6 +235,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
37 if req.ContentLength == 0 {
38 outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
39 }
40+ if outreq.Body != nil {
41+ // Reading from the request body after returning from a handler is not
42+ // allowed, and the RoundTrip goroutine that reads the Body can outlive
43+ // this handler. This can lead to a crash if the handler panics (see
44+ // Issue 46866). Although calling Close doesn't guarantee there isn't
45+ // any Read in flight after the handle returns, in practice it's safe to
46+ // read after closing it.
47+ defer outreq.Body.Close()
48+ }
49 if outreq.Header == nil {
50 outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
51 }
52diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
53index 1898ed8b8afde..4b6ad77a29466 100644
54--- a/src/net/http/httputil/reverseproxy_test.go
55+++ b/src/net/http/httputil/reverseproxy_test.go
56@@ -1122,6 +1122,45 @@ func TestReverseProxy_PanicBodyError(t *testing.T) {
57 rproxy.ServeHTTP(httptest.NewRecorder(), req)
58 }
59
60+// Issue #46866: panic without closing incoming request body causes a panic
61+func TestReverseProxy_PanicClosesIncomingBody(t *testing.T) {
62+ backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
63+ out := "this call was relayed by the reverse proxy"
64+ // Coerce a wrong content length to induce io.ErrUnexpectedEOF
65+ w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out)*2))
66+ fmt.Fprintln(w, out)
67+ }))
68+ defer backend.Close()
69+ backendURL, err := url.Parse(backend.URL)
70+ if err != nil {
71+ t.Fatal(err)
72+ }
73+ proxyHandler := NewSingleHostReverseProxy(backendURL)
74+ proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
75+ frontend := httptest.NewServer(proxyHandler)
76+ defer frontend.Close()
77+ frontendClient := frontend.Client()
78+
79+ var wg sync.WaitGroup
80+ for i := 0; i < 2; i++ {
81+ wg.Add(1)
82+ go func() {
83+ defer wg.Done()
84+ for j := 0; j < 10; j++ {
85+ const reqLen = 6 * 1024 * 1024
86+ req, _ := http.NewRequest("POST", frontend.URL, &io.LimitedReader{R: neverEnding('x'), N: reqLen})
87+ req.ContentLength = reqLen
88+ resp, _ := frontendClient.Transport.RoundTrip(req)
89+ if resp != nil {
90+ io.Copy(io.Discard, resp.Body)
91+ resp.Body.Close()
92+ }
93+ }
94+ }()
95+ }
96+ wg.Wait()
97+}
98+
99 func TestSelectFlushInterval(t *testing.T) {
100 tests := []struct {
101 name string
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2021-39293.patch b/meta/recipes-devtools/go/go-1.14/CVE-2021-39293.patch
new file mode 100644
index 0000000000..88fca9cad9
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2021-39293.patch
@@ -0,0 +1,79 @@
1From 6c480017ae600b2c90a264a922e041df04dfa785 Mon Sep 17 00:00:00 2001
2From: Roland Shoemaker <roland@golang.org>
3Date: Wed, 18 Aug 2021 11:49:29 -0700
4Subject: [PATCH] [release-branch.go1.16] archive/zip: prevent preallocation
5 check from overflowing
6
7If the indicated directory size in the archive header is so large that
8subtracting it from the archive size overflows a uint64, the check that
9the indicated number of files in the archive can be effectively
10bypassed. Prevent this from happening by checking that the indicated
11directory size is less than the size of the archive.
12
13Thanks to the OSS-Fuzz project for discovering this issue and to
14Emmanuel Odeke for reporting it.
15
16Fixes #47985
17Updates #47801
18Fixes CVE-2021-39293
19
20Change-Id: Ifade26b98a40f3b37398ca86bd5252d12394dd24
21Reviewed-on: https://go-review.googlesource.com/c/go/+/343434
22Trust: Roland Shoemaker <roland@golang.org>
23Run-TryBot: Roland Shoemaker <roland@golang.org>
24TryBot-Result: Go Bot <gobot@golang.org>
25Reviewed-by: Russ Cox <rsc@golang.org>
26(cherry picked from commit bacbc33439b124ffd7392c91a5f5d96eca8c0c0b)
27Reviewed-on: https://go-review.googlesource.com/c/go/+/345409
28Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
29Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
30Trust: Cherry Mui <cherryyz@google.com>
31
32https://github.com/golang/go/commit/6c480017ae600b2c90a264a922e041df04dfa785
33CVE: CVE-2021-39293
34Upstream-Status: Backport
35Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
36---
37 src/archive/zip/reader.go | 2 +-
38 src/archive/zip/reader_test.go | 18 ++++++++++++++++++
39 2 files changed, 19 insertions(+), 1 deletion(-)
40
41diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
42index ddef2b7b5a517..801d1313b6c32 100644
43--- a/src/archive/zip/reader.go
44+++ b/src/archive/zip/reader.go
45@@ -105,7 +105,7 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
46 // indicate it contains up to 1 << 128 - 1 files. Since each file has a
47 // header which will be _at least_ 30 bytes we can safely preallocate
48 // if (data size / 30) >= end.directoryRecords.
49- if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
50+ if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
51 z.File = make([]*File, 0, end.directoryRecords)
52 }
53 z.Comment = end.comment
54diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
55index 471be27bb1004..99f13345d8d06 100644
56--- a/src/archive/zip/reader_test.go
57+++ b/src/archive/zip/reader_test.go
58@@ -1225,3 +1225,21 @@ func TestCVE202133196(t *testing.T) {
59 t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
60 }
61 }
62+
63+func TestCVE202139293(t *testing.T) {
64+ // directory size is so large, that the check in Reader.init
65+ // overflows when subtracting from the archive size, causing
66+ // the pre-allocation check to be bypassed.
67+ data := []byte{
68+ 0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
69+ 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
70+ 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
71+ 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
72+ 0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
73+ 0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff,
74+ }
75+ _, err := NewReader(bytes.NewReader(data), int64(len(data)))
76+ if err != ErrFormat {
77+ t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
78+ }
79+}
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2021-41771.patch b/meta/recipes-devtools/go/go-1.14/CVE-2021-41771.patch
new file mode 100644
index 0000000000..526796dbcb
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2021-41771.patch
@@ -0,0 +1,86 @@
1From d19c5bdb24e093a2d5097b7623284eb02726cede Mon Sep 17 00:00:00 2001
2From: Roland Shoemaker <roland@golang.org>
3Date: Thu, 14 Oct 2021 13:02:01 -0700
4Subject: [PATCH] [release-branch.go1.16] debug/macho: fail on invalid dynamic
5 symbol table command
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Fail out when loading a file that contains a dynamic symbol table
11command that indicates a larger number of symbols than exist in the
12loaded symbol table.
13
14Thanks to Burak Çarıkçı - Yunus Yıldırım (CT-Zer0 Crypttech) for
15reporting this issue.
16
17Updates #48990
18Fixes #48991
19Fixes CVE-2021-41771
20
21Change-Id: Ic3d6e6529241afcc959544b326b21b663262bad5
22Reviewed-on: https://go-review.googlesource.com/c/go/+/355990
23Reviewed-by: Julie Qiu <julie@golang.org>
24Reviewed-by: Katie Hockman <katie@golang.org>
25Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
26Run-TryBot: Roland Shoemaker <roland@golang.org>
27TryBot-Result: Go Bot <gobot@golang.org>
28Trust: Katie Hockman <katie@golang.org>
29(cherry picked from commit 61536ec03063b4951163bd09609c86d82631fa27)
30Reviewed-on: https://go-review.googlesource.com/c/go/+/359454
31Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
32
33https://github.com/golang/go/commit/d19c5bdb24e093a2d5097b7623284eb02726cede
34CVE: CVE-2021-41771
35Upstream-Status: Backport
36Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
37---
38 src/debug/macho/file.go | 9 +++++++++
39 src/debug/macho/file_test.go | 7 +++++++
40 .../testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64 | 1 +
41 3 files changed, 17 insertions(+)
42 create mode 100644 src/debug/macho/testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64
43
44diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go
45index 085b0c8219bad..73cfce3c7606e 100644
46--- a/src/debug/macho/file.go
47+++ b/src/debug/macho/file.go
48@@ -345,6 +345,15 @@ func NewFile(r io.ReaderAt) (*File, error) {
49 if err := binary.Read(b, bo, &hdr); err != nil {
50 return nil, err
51 }
52+ if hdr.Iundefsym > uint32(len(f.Symtab.Syms)) {
53+ return nil, &FormatError{offset, fmt.Sprintf(
54+ "undefined symbols index in dynamic symbol table command is greater than symbol table length (%d > %d)",
55+ hdr.Iundefsym, len(f.Symtab.Syms)), nil}
56+ } else if hdr.Iundefsym+hdr.Nundefsym > uint32(len(f.Symtab.Syms)) {
57+ return nil, &FormatError{offset, fmt.Sprintf(
58+ "number of undefined symbols after index in dynamic symbol table command is greater than symbol table length (%d > %d)",
59+ hdr.Iundefsym+hdr.Nundefsym, len(f.Symtab.Syms)), nil}
60+ }
61 dat := make([]byte, hdr.Nindirectsyms*4)
62 if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
63 return nil, err
64diff --git a/src/debug/macho/file_test.go b/src/debug/macho/file_test.go
65index 03915c86e23d9..9beeb80dd27c1 100644
66--- a/src/debug/macho/file_test.go
67+++ b/src/debug/macho/file_test.go
68@@ -416,3 +416,10 @@ func TestTypeString(t *testing.T) {
69 t.Errorf("got %v, want %v", TypeExec.GoString(), "macho.Exec")
70 }
71 }
72+
73+func TestOpenBadDysymCmd(t *testing.T) {
74+ _, err := openObscured("testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64")
75+ if err == nil {
76+ t.Fatal("openObscured did not fail when opening a file with an invalid dynamic symbol table command")
77+ }
78+}
79diff --git a/src/debug/macho/testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64 b/src/debug/macho/testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64
80new file mode 100644
81index 0000000000000..8e0436639c109
82--- /dev/null
83+++ b/src/debug/macho/testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64
84@@ -0,0 +1 @@
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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqAEiJ5UiD5PBIi30ISI11EIn6g8IBweIDSAHySInR6wRIg8EISIM5AHX2SIPBCOgiAAAAicfoMgAAAPRBU0yNHafw//9BU/8lvwAAAA8fAP8lvgAAAFVIieVIjT0zAAAA6A0AAAC4AAAAAMnD/yXRAAAA/yXTAAAAAAAATI0dwQAAAOm0////TI0dvQAAAOmo////aGVsbG8sIHdvcmxkAAAAABQAAAAAAAAAAXpSAAF4EAEQDAcIkAEAACwAAAAcAAAAkv////////8XAAAAAAAAAAAEAQAAAA4QhgIEAwAAAA0GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDAX/9/AAAIEMBf/38AAAAAAAABAAAAGBAAAAEAAAAQEAAAAQAAAAgQAAABAAAAABAAAAEAAACQDwAAAQAAAJwPAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAHgEAAFAPAAABAAAAGwAAAB4BAABkDwAAAQAAAC4AAAAPBgAAGBAAAAEAAAA2AAAADwYAABAQAAABAAAAPgAAAA8GAAAAEAAAAQAAAEoAAAADABAAAAAAAAEAAABeAAAADwYAAAgQAAABAAAAZwAAAA8BAABqDwAAAQAAAG0AAAAPAQAAFA8AAAEAAABzAAAAAQABAgAAAAAAAAAAeQAAAAEAAQIAAAAAAAAAAAkAAAAKAAAACQAAAAoAAAAgAGR5bGRfc3R1Yl9iaW5kaW5nX2hlbHBlcgBfX2R5bGRfZnVuY19sb29rdXAAX05YQXJnYwBfTlhBcmd2AF9fX3Byb2duYW1lAF9fbWhfZXhlY3V0ZV9oZWFkZXIAX2Vudmlyb24AX21haW4Ac3RhcnQAX2V4aXQAX3B1dHMAAA==
86\ No newline at end of file