diff mbox series

[dunfell] go: fix and ignore several CVEs

Message ID 20220914151449.64143-1-chee.yang.lee@intel.com
State Accepted, archived
Commit ddb09ccc3caebbd3cf643bb3bb3c198845050c69
Headers show
Series [dunfell] go: fix and ignore several CVEs | expand

Commit Message

Lee, Chee Yang Sept. 14, 2022, 3:14 p.m. UTC
From: Chee Yang Lee <chee.yang.lee@intel.com>

backport fixes:
CVE-2021-27918
CVE-2021-36221
CVE-2021-39293
CVE-2021-41771

ignore:
CVE-2022-29526
CVE-2022-30634

Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
---
 meta/recipes-devtools/go/go-1.14.inc          |  10 +
 .../go/go-1.14/CVE-2021-27918.patch           | 191 ++++++++++++++++++
 .../go/go-1.14/CVE-2021-36221.patch           | 101 +++++++++
 .../go/go-1.14/CVE-2021-39293.patch           |  79 ++++++++
 .../go/go-1.14/CVE-2021-41771.patch           |  86 ++++++++
 5 files changed, 467 insertions(+)
 create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2021-27918.patch
 create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2021-36221.patch
 create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2021-39293.patch
 create mode 100644 meta/recipes-devtools/go/go-1.14/CVE-2021-41771.patch
diff mbox series

Patch

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 += "\
     file://CVE-2022-30635.patch \
     file://CVE-2022-32148.patch \
     file://CVE-2022-32189.patch \
+    file://CVE-2021-27918.patch \
+    file://CVE-2021-36221.patch \
+    file://CVE-2021-39293.patch \
+    file://CVE-2021-41771.patch \
 "
 
 SRC_URI_append_libc-musl = " file://0009-ld-replace-glibc-dynamic-linker-with-musl.patch"
@@ -42,3 +46,9 @@  SRC_URI[main.sha256sum] = "7ed13b2209e54a451835997f78035530b331c5b6943cdcd68a3d8
 # https://github.com/golang/go/issues/30999#issuecomment-910470358
 CVE_CHECK_WHITELIST += "CVE-2021-29923"
 
+# this issue affected go1.15 onwards
+# https://security-tracker.debian.org/tracker/CVE-2022-29526
+CVE_CHECK_WHITELIST += "CVE-2022-29526"
+
+# Issue only on windows
+CVE_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 @@ 
+From d0b79e3513a29628f3599dc8860666b6eed75372 Mon Sep 17 00:00:00 2001
+From: Katie Hockman <katie@golang.org>
+Date: Mon, 1 Mar 2021 09:54:00 -0500
+Subject: [PATCH] encoding/xml: prevent infinite loop while decoding
+
+This change properly handles a TokenReader which
+returns an EOF in the middle of an open XML
+element.
+
+Thanks to Sam Whited for reporting this.
+
+Fixes CVE-2021-27918
+Fixes #44913
+
+Change-Id: Id02a3f3def4a1b415fa2d9a8e3b373eb6cb0f433
+Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1004594
+Reviewed-by: Russ Cox <rsc@google.com>
+Reviewed-by: Roland Shoemaker <bracewell@google.com>
+Reviewed-by: Filippo Valsorda <valsorda@google.com>
+Reviewed-on: https://go-review.googlesource.com/c/go/+/300391
+Trust: Katie Hockman <katie@golang.org>
+Run-TryBot: Katie Hockman <katie@golang.org>
+TryBot-Result: Go Bot <gobot@golang.org>
+Reviewed-by: Alexander Rakoczy <alex@golang.org>
+Reviewed-by: Filippo Valsorda <filippo@golang.org>
+
+https://github.com/golang/go/commit/d0b79e3513a29628f3599dc8860666b6eed75372
+CVE: CVE-2021-27918
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ src/encoding/xml/xml.go      |  19 ++++---
+ src/encoding/xml/xml_test.go | 104 +++++++++++++++++++++++++++--------
+ 2 files changed, 92 insertions(+), 31 deletions(-)
+
+diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
+index adaf4daf198b9..6f9594d7ba7a3 100644
+--- a/src/encoding/xml/xml.go
++++ b/src/encoding/xml/xml.go
+@@ -271,7 +271,7 @@ func NewTokenDecoder(t TokenReader) *Decoder {
+ // it will return an error.
+ //
+ // Token implements XML name spaces as described by
+-// https://www.w3.org/TR/REC-xml-names/.  Each of the
++// https://www.w3.org/TR/REC-xml-names/. Each of the
+ // Name structures contained in the Token has the Space
+ // set to the URL identifying its name space when known.
+ // If Token encounters an unrecognized name space prefix,
+@@ -285,16 +285,17 @@ func (d *Decoder) Token() (Token, error) {
+ 	if d.nextToken != nil {
+ 		t = d.nextToken
+ 		d.nextToken = nil
+-	} else if t, err = d.rawToken(); err != nil {
+-		switch {
+-		case err == io.EOF && d.t != nil:
+-			err = nil
+-		case err == io.EOF && d.stk != nil && d.stk.kind != stkEOF:
+-			err = d.syntaxError("unexpected EOF")
++	} else {
++		if t, err = d.rawToken(); t == nil && err != nil {
++			if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
++				err = d.syntaxError("unexpected EOF")
++			}
++			return nil, err
+ 		}
+-		return t, err
++		// We still have a token to process, so clear any
++		// errors (e.g. EOF) and proceed.
++		err = nil
+ 	}
+-
+ 	if !d.Strict {
+ 		if t1, ok := d.autoClose(t); ok {
+ 			d.nextToken = t
+diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
+index efddca43e9102..5672ebb375f0d 100644
+--- a/src/encoding/xml/xml_test.go
++++ b/src/encoding/xml/xml_test.go
+@@ -33,30 +33,90 @@ func (t *toks) Token() (Token, error) {
+ 
+ func TestDecodeEOF(t *testing.T) {
+ 	start := StartElement{Name: Name{Local: "test"}}
+-	t.Run("EarlyEOF", func(t *testing.T) {
+-		d := NewTokenDecoder(&toks{earlyEOF: true, t: []Token{
+-			start,
+-			start.End(),
+-		}})
+-		err := d.Decode(&struct {
+-			XMLName Name `xml:"test"`
+-		}{})
+-		if err != nil {
+-			t.Error(err)
++	tests := []struct {
++		name   string
++		tokens []Token
++		ok     bool
++	}{
++		{
++			name: "OK",
++			tokens: []Token{
++				start,
++				start.End(),
++			},
++			ok: true,
++		},
++		{
++			name: "Malformed",
++			tokens: []Token{
++				start,
++				StartElement{Name: Name{Local: "bad"}},
++				start.End(),
++			},
++			ok: false,
++		},
++	}
++	for _, tc := range tests {
++		for _, eof := range []bool{true, false} {
++			name := fmt.Sprintf("%s/earlyEOF=%v", tc.name, eof)
++			t.Run(name, func(t *testing.T) {
++				d := NewTokenDecoder(&toks{
++					earlyEOF: eof,
++					t:        tc.tokens,
++				})
++				err := d.Decode(&struct {
++					XMLName Name `xml:"test"`
++				}{})
++				if tc.ok && err != nil {
++					t.Fatalf("d.Decode: expected nil error, got %v", err)
++				}
++				if _, ok := err.(*SyntaxError); !tc.ok && !ok {
++					t.Errorf("d.Decode: expected syntax error, got %v", err)
++				}
++			})
+ 		}
+-	})
+-	t.Run("LateEOF", func(t *testing.T) {
+-		d := NewTokenDecoder(&toks{t: []Token{
+-			start,
+-			start.End(),
+-		}})
+-		err := d.Decode(&struct {
+-			XMLName Name `xml:"test"`
+-		}{})
+-		if err != nil {
+-			t.Error(err)
++	}
++}
++
++type toksNil struct {
++	returnEOF bool
++	t         []Token
++}
++
++func (t *toksNil) Token() (Token, error) {
++	if len(t.t) == 0 {
++		if !t.returnEOF {
++			// Return nil, nil before returning an EOF. It's legal, but
++			// discouraged.
++			t.returnEOF = true
++			return nil, nil
+ 		}
+-	})
++		return nil, io.EOF
++	}
++	var tok Token
++	tok, t.t = t.t[0], t.t[1:]
++	return tok, nil
++}
++
++func TestDecodeNilToken(t *testing.T) {
++	for _, strict := range []bool{true, false} {
++		name := fmt.Sprintf("Strict=%v", strict)
++		t.Run(name, func(t *testing.T) {
++			start := StartElement{Name: Name{Local: "test"}}
++			bad := StartElement{Name: Name{Local: "bad"}}
++			d := NewTokenDecoder(&toksNil{
++				// Malformed
++				t: []Token{start, bad, start.End()},
++			})
++			d.Strict = strict
++			err := d.Decode(&struct {
++				XMLName Name `xml:"test"`
++			}{})
++			if _, ok := err.(*SyntaxError); !ok {
++				t.Errorf("d.Decode: expected syntax error, got %v", err)
++			}
++		})
++	}
+ }
+ 
+ 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 @@ 
+From b7a85e0003cedb1b48a1fd3ae5b746ec6330102e Mon Sep 17 00:00:00 2001
+From: Damien Neil <dneil@google.com>
+Date: Wed, 7 Jul 2021 16:34:34 -0700
+Subject: [PATCH] net/http/httputil: close incoming ReverseProxy request body
+
+Reading from an incoming request body after the request handler aborts
+with a panic can cause a panic, becuse http.Server does not (contrary
+to its documentation) close the request body in this case.
+
+Always close the incoming request body in ReverseProxy.ServeHTTP to
+ensure that any in-flight outgoing requests using the body do not
+read from it.
+
+Updates #46866
+Fixes CVE-2021-36221
+
+Change-Id: I310df269200ad8732c5d9f1a2b00de68725831df
+Reviewed-on: https://go-review.googlesource.com/c/go/+/333191
+Trust: Damien Neil <dneil@google.com>
+Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
+Reviewed-by: Filippo Valsorda <filippo@golang.org>
+
+https://github.com/golang/go/commit/b7a85e0003cedb1b48a1fd3ae5b746ec6330102e 
+CVE: CVE-2021-36221
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ src/net/http/httputil/reverseproxy.go      |  9 +++++
+ src/net/http/httputil/reverseproxy_test.go | 39 ++++++++++++++++++++++
+ 2 files changed, 48 insertions(+)
+
+diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
+index 5d39955d62d15..8b63368386f43 100644
+--- a/src/net/http/httputil/reverseproxy.go
++++ b/src/net/http/httputil/reverseproxy.go
+@@ -235,6 +235,15 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+ 	if req.ContentLength == 0 {
+ 		outreq.Body = nil // Issue 16036: nil Body for http.Transport retries
+ 	}
++	if outreq.Body != nil {
++		// Reading from the request body after returning from a handler is not
++		// allowed, and the RoundTrip goroutine that reads the Body can outlive
++		// this handler. This can lead to a crash if the handler panics (see
++		// Issue 46866). Although calling Close doesn't guarantee there isn't
++		// any Read in flight after the handle returns, in practice it's safe to
++		// read after closing it.
++		defer outreq.Body.Close()
++	}
+ 	if outreq.Header == nil {
+ 		outreq.Header = make(http.Header) // Issue 33142: historical behavior was to always allocate
+ 	}
+diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
+index 1898ed8b8afde..4b6ad77a29466 100644
+--- a/src/net/http/httputil/reverseproxy_test.go
++++ b/src/net/http/httputil/reverseproxy_test.go
+@@ -1122,6 +1122,45 @@ func TestReverseProxy_PanicBodyError(t *testing.T) {
+ 	rproxy.ServeHTTP(httptest.NewRecorder(), req)
+ }
+ 
++// Issue #46866: panic without closing incoming request body causes a panic
++func TestReverseProxy_PanicClosesIncomingBody(t *testing.T) {
++	backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
++		out := "this call was relayed by the reverse proxy"
++		// Coerce a wrong content length to induce io.ErrUnexpectedEOF
++		w.Header().Set("Content-Length", fmt.Sprintf("%d", len(out)*2))
++		fmt.Fprintln(w, out)
++	}))
++	defer backend.Close()
++	backendURL, err := url.Parse(backend.URL)
++	if err != nil {
++		t.Fatal(err)
++	}
++	proxyHandler := NewSingleHostReverseProxy(backendURL)
++	proxyHandler.ErrorLog = log.New(io.Discard, "", 0) // quiet for tests
++	frontend := httptest.NewServer(proxyHandler)
++	defer frontend.Close()
++	frontendClient := frontend.Client()
++
++	var wg sync.WaitGroup
++	for i := 0; i < 2; i++ {
++		wg.Add(1)
++		go func() {
++			defer wg.Done()
++			for j := 0; j < 10; j++ {
++				const reqLen = 6 * 1024 * 1024
++				req, _ := http.NewRequest("POST", frontend.URL, &io.LimitedReader{R: neverEnding('x'), N: reqLen})
++				req.ContentLength = reqLen
++				resp, _ := frontendClient.Transport.RoundTrip(req)
++				if resp != nil {
++					io.Copy(io.Discard, resp.Body)
++					resp.Body.Close()
++				}
++			}
++		}()
++	}
++	wg.Wait()
++}
++
+ func TestSelectFlushInterval(t *testing.T) {
+ 	tests := []struct {
+ 		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 @@ 
+From 6c480017ae600b2c90a264a922e041df04dfa785 Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <roland@golang.org>
+Date: Wed, 18 Aug 2021 11:49:29 -0700
+Subject: [PATCH] [release-branch.go1.16] archive/zip: prevent preallocation
+ check from overflowing
+
+If the indicated directory size in the archive header is so large that
+subtracting it from the archive size overflows a uint64, the check that
+the indicated number of files in the archive can be effectively
+bypassed. Prevent this from happening by checking that the indicated
+directory size is less than the size of the archive.
+
+Thanks to the OSS-Fuzz project for discovering this issue and to
+Emmanuel Odeke for reporting it.
+
+Fixes #47985
+Updates #47801
+Fixes CVE-2021-39293
+
+Change-Id: Ifade26b98a40f3b37398ca86bd5252d12394dd24
+Reviewed-on: https://go-review.googlesource.com/c/go/+/343434
+Trust: Roland Shoemaker <roland@golang.org>
+Run-TryBot: Roland Shoemaker <roland@golang.org>
+TryBot-Result: Go Bot <gobot@golang.org>
+Reviewed-by: Russ Cox <rsc@golang.org>
+(cherry picked from commit bacbc33439b124ffd7392c91a5f5d96eca8c0c0b)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/345409
+Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
+Run-TryBot: Emmanuel Odeke <emmanuel@orijtech.com>
+Trust: Cherry Mui <cherryyz@google.com>
+
+https://github.com/golang/go/commit/6c480017ae600b2c90a264a922e041df04dfa785
+CVE: CVE-2021-39293
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ src/archive/zip/reader.go      |  2 +-
+ src/archive/zip/reader_test.go | 18 ++++++++++++++++++
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
+index ddef2b7b5a517..801d1313b6c32 100644
+--- a/src/archive/zip/reader.go
++++ b/src/archive/zip/reader.go
+@@ -105,7 +105,7 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
+ 	// indicate it contains up to 1 << 128 - 1 files. Since each file has a
+ 	// header which will be _at least_ 30 bytes we can safely preallocate
+ 	// if (data size / 30) >= end.directoryRecords.
+-	if (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
++	if end.directorySize < uint64(size) && (uint64(size)-end.directorySize)/30 >= end.directoryRecords {
+ 		z.File = make([]*File, 0, end.directoryRecords)
+ 	}
+ 	z.Comment = end.comment
+diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
+index 471be27bb1004..99f13345d8d06 100644
+--- a/src/archive/zip/reader_test.go
++++ b/src/archive/zip/reader_test.go
+@@ -1225,3 +1225,21 @@ func TestCVE202133196(t *testing.T) {
+ 		t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File))
+ 	}
+ }
++
++func TestCVE202139293(t *testing.T) {
++	// directory size is so large, that the check in Reader.init
++	// overflows when subtracting from the archive size, causing
++	// the pre-allocation check to be bypassed.
++	data := []byte{
++		0x50, 0x4b, 0x06, 0x06, 0x05, 0x06, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
++		0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
++		0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b,
++		0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
++		0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
++		0xff, 0x50, 0xfe, 0x00, 0xff, 0x00, 0x3a, 0x00, 0x00, 0x00, 0xff,
++	}
++	_, err := NewReader(bytes.NewReader(data), int64(len(data)))
++	if err != ErrFormat {
++		t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat)
++	}
++}
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 @@ 
+From d19c5bdb24e093a2d5097b7623284eb02726cede Mon Sep 17 00:00:00 2001
+From: Roland Shoemaker <roland@golang.org>
+Date: Thu, 14 Oct 2021 13:02:01 -0700
+Subject: [PATCH] [release-branch.go1.16] debug/macho: fail on invalid dynamic
+ symbol table command
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fail out when loading a file that contains a dynamic symbol table
+command that indicates a larger number of symbols than exist in the
+loaded symbol table.
+
+Thanks to Burak Çarıkçı - Yunus Yıldırım (CT-Zer0 Crypttech) for
+reporting this issue.
+
+Updates #48990
+Fixes #48991
+Fixes CVE-2021-41771
+
+Change-Id: Ic3d6e6529241afcc959544b326b21b663262bad5
+Reviewed-on: https://go-review.googlesource.com/c/go/+/355990
+Reviewed-by: Julie Qiu <julie@golang.org>
+Reviewed-by: Katie Hockman <katie@golang.org>
+Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
+Run-TryBot: Roland Shoemaker <roland@golang.org>
+TryBot-Result: Go Bot <gobot@golang.org>
+Trust: Katie Hockman <katie@golang.org>
+(cherry picked from commit 61536ec03063b4951163bd09609c86d82631fa27)
+Reviewed-on: https://go-review.googlesource.com/c/go/+/359454
+Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
+
+https://github.com/golang/go/commit/d19c5bdb24e093a2d5097b7623284eb02726cede
+CVE: CVE-2021-41771
+Upstream-Status: Backport
+Signed-off-by: Chee Yang Lee <chee.yang.lee@intel.com>
+---
+ src/debug/macho/file.go                                  | 9 +++++++++
+ src/debug/macho/file_test.go                             | 7 +++++++
+ .../testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64 | 1 +
+ 3 files changed, 17 insertions(+)
+ create mode 100644 src/debug/macho/testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64
+
+diff --git a/src/debug/macho/file.go b/src/debug/macho/file.go
+index 085b0c8219bad..73cfce3c7606e 100644
+--- a/src/debug/macho/file.go
++++ b/src/debug/macho/file.go
+@@ -345,6 +345,15 @@ func NewFile(r io.ReaderAt) (*File, error) {
+ 			if err := binary.Read(b, bo, &hdr); err != nil {
+ 				return nil, err
+ 			}
++			if hdr.Iundefsym > uint32(len(f.Symtab.Syms)) {
++				return nil, &FormatError{offset, fmt.Sprintf(
++					"undefined symbols index in dynamic symbol table command is greater than symbol table length (%d > %d)",
++					hdr.Iundefsym, len(f.Symtab.Syms)), nil}
++			} else if hdr.Iundefsym+hdr.Nundefsym > uint32(len(f.Symtab.Syms)) {
++				return nil, &FormatError{offset, fmt.Sprintf(
++					"number of undefined symbols after index in dynamic symbol table command is greater than symbol table length (%d > %d)",
++					hdr.Iundefsym+hdr.Nundefsym, len(f.Symtab.Syms)), nil}
++			}
+ 			dat := make([]byte, hdr.Nindirectsyms*4)
+ 			if _, err := r.ReadAt(dat, int64(hdr.Indirectsymoff)); err != nil {
+ 				return nil, err
+diff --git a/src/debug/macho/file_test.go b/src/debug/macho/file_test.go
+index 03915c86e23d9..9beeb80dd27c1 100644
+--- a/src/debug/macho/file_test.go
++++ b/src/debug/macho/file_test.go
+@@ -416,3 +416,10 @@ func TestTypeString(t *testing.T) {
+ 		t.Errorf("got %v, want %v", TypeExec.GoString(), "macho.Exec")
+ 	}
+ }
++
++func TestOpenBadDysymCmd(t *testing.T) {
++	_, err := openObscured("testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64")
++	if err == nil {
++		t.Fatal("openObscured did not fail when opening a file with an invalid dynamic symbol table command")
++	}
++}
+diff --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
+new file mode 100644
+index 0000000000000..8e0436639c109
+--- /dev/null
++++ b/src/debug/macho/testdata/gcc-amd64-darwin-exec-with-bad-dysym.base64
+@@ -0,0 +1 @@
++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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABqAEiJ5UiD5PBIi30ISI11EIn6g8IBweIDSAHySInR6wRIg8EISIM5AHX2SIPBCOgiAAAAicfoMgAAAPRBU0yNHafw//9BU/8lvwAAAA8fAP8lvgAAAFVIieVIjT0zAAAA6A0AAAC4AAAAAMnD/yXRAAAA/yXTAAAAAAAATI0dwQAAAOm0////TI0dvQAAAOmo////aGVsbG8sIHdvcmxkAAAAABQAAAAAAAAAAXpSAAF4EAEQDAcIkAEAACwAAAAcAAAAkv////////8XAAAAAAAAAAAEAQAAAA4QhgIEAwAAAA0GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDAX/9/AAAIEMBf/38AAAAAAAABAAAAGBAAAAEAAAAQEAAAAQAAAAgQAAABAAAAABAAAAEAAACQDwAAAQAAAJwPAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAHgEAAFAPAAABAAAAGwAAAB4BAABkDwAAAQAAAC4AAAAPBgAAGBAAAAEAAAA2AAAADwYAABAQAAABAAAAPgAAAA8GAAAAEAAAAQAAAEoAAAADABAAAAAAAAEAAABeAAAADwYAAAgQAAABAAAAZwAAAA8BAABqDwAAAQAAAG0AAAAPAQAAFA8AAAEAAABzAAAAAQABAgAAAAAAAAAAeQAAAAEAAQIAAAAAAAAAAAkAAAAKAAAACQAAAAoAAAAgAGR5bGRfc3R1Yl9iaW5kaW5nX2hlbHBlcgBfX2R5bGRfZnVuY19sb29rdXAAX05YQXJnYwBfTlhBcmd2AF9fX3Byb2duYW1lAF9fbWhfZXhlY3V0ZV9oZWFkZXIAX2Vudmlyb24AX21haW4Ac3RhcnQAX2V4aXQAX3B1dHMAAA==
+\ No newline at end of file