From c7248a0c9408552e7748a5cbdbee63c5535c8c83 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Tue, 27 Apr 2021 15:05:51 -0500 Subject: [release-branch.go1.16] cmd/link: disable plugin support if cgo is disabled Functional plugin support requires cgo to be enabled. Disable it if the environment has disabled cgo. This prevents unexpected linker failures when linking large binaries with cgo disabled which use the plugin package. Fixes #45832 Change-Id: Ib71f0e089f7373b7b3e3cd53da3612291e7bc473 Reviewed-on: https://go-review.googlesource.com/c/go/+/314449 Run-TryBot: Paul Murphy Reviewed-by: Cherry Zhang TryBot-Result: Go Bot Trust: Lynn Boger (cherry picked from commit 983dea90c169930e35721232afe39fd4e3fbe4a6) Reviewed-on: https://go-review.googlesource.com/c/go/+/316329 Reviewed-by: Cherry Mui Trust: Dmitri Shuralyov --- src/cmd/link/internal/ld/lib.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 17d5040827..18db567041 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -533,7 +533,10 @@ func (ctxt *Link) loadlib() { // up symbol by name may not get expected result. iscgo = ctxt.LibraryByPkg["runtime/cgo"] != nil - ctxt.canUsePlugins = ctxt.LibraryByPkg["plugin"] != nil + + // Plugins a require cgo support to function. Similarly, plugins may require additional + // internal linker support on some platforms which may not be implemented. + ctxt.canUsePlugins = ctxt.LibraryByPkg["plugin"] != nil && iscgo // We now have enough information to determine the link mode. determineLinkMode(ctxt) -- cgit v1.2.3-54-g00ecf From 305fa952c23b67e03a21d30318b945fddb2f3916 Mon Sep 17 00:00:00 2001 From: Cherry Mui Date: Tue, 11 May 2021 22:40:02 -0400 Subject: [release-branch.go1.16] cmd/link: don't cast end address to int32 When linking a very large binary, the section address may not fit in int32. Don't truncate it. Fixes #46128. Updates #46126. Change-Id: Ibcc8d74bf5662611949e547ce44ca8b973de383f Reviewed-on: https://go-review.googlesource.com/c/go/+/319289 Trust: Cherry Mui Run-TryBot: Cherry Mui Reviewed-by: Than McIntosh TryBot-Result: Go Bot (cherry picked from commit af0f8c149e8a4b237910fc7b41739bedc546473c) Reviewed-on: https://go-review.googlesource.com/c/go/+/319369 --- src/cmd/link/internal/ld/elf.go | 2 +- src/cmd/link/internal/ld/macho.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go index 37b2dc640d..f5823a8fbf 100644 --- a/src/cmd/link/internal/ld/elf.go +++ b/src/cmd/link/internal/ld/elf.go @@ -1086,7 +1086,7 @@ func elfrelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sym) } } - eaddr := int32(sect.Vaddr + sect.Length) + eaddr := sect.Vaddr + sect.Length for _, s := range syms { if !ldr.AttrReachable(s) { continue diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 3630e67c25..a9f4d87229 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go @@ -1168,7 +1168,7 @@ func machorelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sy } } - eaddr := int32(sect.Vaddr + sect.Length) + eaddr := sect.Vaddr + sect.Length for _, s := range syms { if !ldr.AttrReachable(s) { continue -- cgit v1.2.3-54-g00ecf From 9210eaf7dc704612a6eda97c482012f779fd833b Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Sun, 2 May 2021 11:27:03 -0700 Subject: [release-branch.go1.16] math/big: check for excessive exponents in Rat.SetString Found by OSS-Fuzz https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=33284 Thanks to Emmanuel Odeke for reporting this issue. Updates #45910 Fixes #46306 Fixes CVE-2021-33198 Change-Id: I61e7b04dbd80343420b57eede439e361c0f7b79c Reviewed-on: https://go-review.googlesource.com/c/go/+/316149 Trust: Robert Griesemer Trust: Katie Hockman Run-TryBot: Robert Griesemer TryBot-Result: Go Bot Reviewed-by: Katie Hockman Reviewed-by: Emmanuel Odeke (cherry picked from commit 6c591f79b0b5327549bd4e94970f7a279efb4ab0) Reviewed-on: https://go-review.googlesource.com/c/go/+/321832 Run-TryBot: Katie Hockman Reviewed-by: Roland Shoemaker --- src/math/big/ratconv.go | 15 ++++++++------- src/math/big/ratconv_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/math/big/ratconv.go b/src/math/big/ratconv.go index 941139e72d..ac3c8bd11f 100644 --- a/src/math/big/ratconv.go +++ b/src/math/big/ratconv.go @@ -51,7 +51,8 @@ func (z *Rat) Scan(s fmt.ScanState, ch rune) error { // An optional base-10 ``e'' or base-2 ``p'' (or their upper-case variants) // exponent may be provided as well, except for hexadecimal floats which // only accept an (optional) ``p'' exponent (because an ``e'' or ``E'' cannot -// be distinguished from a mantissa digit). +// be distinguished from a mantissa digit). If the exponent's absolute value +// is too large, the operation may fail. // The entire string, not just a prefix, must be valid for success. If the // operation failed, the value of z is undefined but the returned value is nil. func (z *Rat) SetString(s string) (*Rat, bool) { @@ -169,6 +170,9 @@ func (z *Rat) SetString(s string) (*Rat, bool) { if n < 0 { n = -n } + if n > 1e6 { + return nil, false // avoid excessively large exponents + } pow5 := z.b.abs.expNN(natFive, nat(nil).setWord(Word(n)), nil) // use underlying array of z.b.abs if exp5 > 0 { z.a.abs = z.a.abs.mul(z.a.abs, pow5) @@ -181,15 +185,12 @@ func (z *Rat) SetString(s string) (*Rat, bool) { } // apply exp2 contributions + if exp2 < -1e7 || exp2 > 1e7 { + return nil, false // avoid excessively large exponents + } if exp2 > 0 { - if int64(uint(exp2)) != exp2 { - panic("exponent too large") - } z.a.abs = z.a.abs.shl(z.a.abs, uint(exp2)) } else if exp2 < 0 { - if int64(uint(-exp2)) != -exp2 { - panic("exponent too large") - } z.b.abs = z.b.abs.shl(z.b.abs, uint(-exp2)) } diff --git a/src/math/big/ratconv_test.go b/src/math/big/ratconv_test.go index ba0d1ba9e1..15d206cb38 100644 --- a/src/math/big/ratconv_test.go +++ b/src/math/big/ratconv_test.go @@ -589,3 +589,28 @@ func TestIssue31184(t *testing.T) { } } } + +func TestIssue45910(t *testing.T) { + var x Rat + for _, test := range []struct { + input string + want bool + }{ + {"1e-1000001", false}, + {"1e-1000000", true}, + {"1e+1000000", true}, + {"1e+1000001", false}, + + {"0p1000000000000", true}, + {"1p-10000001", false}, + {"1p-10000000", true}, + {"1p+10000000", true}, + {"1p+10000001", false}, + {"1.770p02041010010011001001", false}, // test case from issue + } { + _, got := x.SetString(test.input) + if got != test.want { + t.Errorf("SetString(%s) got ok = %v; want %v", test.input, got, test.want) + } + } +} -- cgit v1.2.3-54-g00ecf From df6a737cc899507d3090e995abd1e1ed1a30cee3 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Thu, 27 May 2021 10:40:06 -0700 Subject: [release-branch.go1.16] net: verify results from Lookup* are valid domain names For the methods LookupCNAME, LookupSRV, LookupMX, LookupNS, and LookupAddr check that the returned domain names are in fact valid DNS names using the existing isDomainName function. Thanks to Philipp Jeitner and Haya Shulman from Fraunhofer SIT for reporting this issue. Updates #46241 Fixes #46357 Fixes CVE-2021-33195 Change-Id: I47a4f58c031cb752f732e88bbdae7f819f0af4f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/323131 Trust: Roland Shoemaker Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Reviewed-by: Filippo Valsorda Reviewed-by: Katie Hockman (cherry picked from commit cdcd02842da7c004efd023881e3719105209c908) Reviewed-on: https://go-review.googlesource.com/c/go/+/323270 --- src/net/dnsclient_unix_test.go | 157 +++++++++++++++++++++++++++++++++++++++++ src/net/lookup.go | 111 +++++++++++++++++++++++++---- 2 files changed, 255 insertions(+), 13 deletions(-) diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index 0530c92c2e..5d3df49bdf 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -1798,3 +1798,160 @@ func TestPTRandNonPTR(t *testing.T) { t.Errorf("names = %q; want %q", names, want) } } + +func TestCVE202133195(t *testing.T) { + fake := fakeDNSServer{ + rh: func(n, _ string, q dnsmessage.Message, _ time.Time) (dnsmessage.Message, error) { + r := dnsmessage.Message{ + Header: dnsmessage.Header{ + ID: q.Header.ID, + Response: true, + RCode: dnsmessage.RCodeSuccess, + RecursionAvailable: true, + }, + Questions: q.Questions, + } + switch q.Questions[0].Type { + case dnsmessage.TypeCNAME: + r.Answers = []dnsmessage.Resource{} + case dnsmessage.TypeA: // CNAME lookup uses a A/AAAA as a proxy + r.Answers = append(r.Answers, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName(".golang.org."), + Type: dnsmessage.TypeA, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.AResource{ + A: TestAddr, + }, + }, + ) + case dnsmessage.TypeSRV: + n := q.Questions[0].Name + if n.String() == "_hdr._tcp.golang.org." { + n = dnsmessage.MustNewName(".golang.org.") + } + r.Answers = append(r.Answers, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: n, + Type: dnsmessage.TypeSRV, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.SRVResource{ + Target: dnsmessage.MustNewName(".golang.org."), + }, + }, + ) + case dnsmessage.TypeMX: + r.Answers = append(r.Answers, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName(".golang.org."), + Type: dnsmessage.TypeMX, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.MXResource{ + MX: dnsmessage.MustNewName(".golang.org."), + }, + }, + ) + case dnsmessage.TypeNS: + r.Answers = append(r.Answers, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName(".golang.org."), + Type: dnsmessage.TypeNS, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.NSResource{ + NS: dnsmessage.MustNewName(".golang.org."), + }, + }, + ) + case dnsmessage.TypePTR: + r.Answers = append(r.Answers, + dnsmessage.Resource{ + Header: dnsmessage.ResourceHeader{ + Name: dnsmessage.MustNewName(".golang.org."), + Type: dnsmessage.TypePTR, + Class: dnsmessage.ClassINET, + Length: 4, + }, + Body: &dnsmessage.PTRResource{ + PTR: dnsmessage.MustNewName(".golang.org."), + }, + }, + ) + } + return r, nil + }, + } + + r := Resolver{PreferGo: true, Dial: fake.DialContext} + // Change the default resolver to match our manipulated resolver + originalDefault := DefaultResolver + DefaultResolver = &r + defer func() { + DefaultResolver = originalDefault + }() + + _, err := r.LookupCNAME(context.Background(), "golang.org") + if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected) + } + _, err = LookupCNAME("golang.org") + if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected) + } + + _, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org") + if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + } + _, _, err = LookupSRV("target", "tcp", "golang.org") + if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + } + + _, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org") + if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + } + _, _, err = LookupSRV("hdr", "tcp", "golang.org") + if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + } + + _, err = r.LookupMX(context.Background(), "golang.org") + if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err.Error(), expected) + } + _, err = LookupMX("golang.org") + if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupMX returned unexpected error, got %q, want %q", err.Error(), expected) + } + + _, err = r.LookupNS(context.Background(), "golang.org") + if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err.Error(), expected) + } + _, err = LookupNS("golang.org") + if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupNS returned unexpected error, got %q, want %q", err.Error(), expected) + } + + _, err = r.LookupAddr(context.Background(), "1.2.3.4") + if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected) + } + _, err = LookupAddr("1.2.3.4") + if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected) + } +} diff --git a/src/net/lookup.go b/src/net/lookup.go index 5f7119872a..0660268249 100644 --- a/src/net/lookup.go +++ b/src/net/lookup.go @@ -389,8 +389,11 @@ func (r *Resolver) LookupPort(ctx context.Context, network, service string) (por // LookupCNAME does not return an error if host does not // contain DNS "CNAME" records, as long as host resolves to // address records. +// +// The returned canonical name is validated to be a properly +// formatted presentation-format domain name. func LookupCNAME(host string) (cname string, err error) { - return DefaultResolver.lookupCNAME(context.Background(), host) + return DefaultResolver.LookupCNAME(context.Background(), host) } // LookupCNAME returns the canonical name for the given host. @@ -403,8 +406,18 @@ func LookupCNAME(host string) (cname string, err error) { // LookupCNAME does not return an error if host does not // contain DNS "CNAME" records, as long as host resolves to // address records. -func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string, err error) { - return r.lookupCNAME(ctx, host) +// +// The returned canonical name is validated to be a properly +// formatted presentation-format domain name. +func (r *Resolver) LookupCNAME(ctx context.Context, host string) (string, error) { + cname, err := r.lookupCNAME(ctx, host) + if err != nil { + return "", err + } + if !isDomainName(cname) { + return "", &DNSError{Err: "CNAME target is invalid", Name: host} + } + return cname, nil } // LookupSRV tries to resolve an SRV query of the given service, @@ -416,8 +429,11 @@ func (r *Resolver) LookupCNAME(ctx context.Context, host string) (cname string, // That is, it looks up _service._proto.name. To accommodate services // publishing SRV records under non-standard names, if both service // and proto are empty strings, LookupSRV looks up name directly. +// +// The returned service names are validated to be properly +// formatted presentation-format domain names. func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { - return DefaultResolver.lookupSRV(context.Background(), service, proto, name) + return DefaultResolver.LookupSRV(context.Background(), service, proto, name) } // LookupSRV tries to resolve an SRV query of the given service, @@ -429,28 +445,82 @@ func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err err // That is, it looks up _service._proto.name. To accommodate services // publishing SRV records under non-standard names, if both service // and proto are empty strings, LookupSRV looks up name directly. -func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*SRV, err error) { - return r.lookupSRV(ctx, service, proto, name) +// +// The returned service names are validated to be properly +// formatted presentation-format domain names. +func (r *Resolver) LookupSRV(ctx context.Context, service, proto, name string) (string, []*SRV, error) { + cname, addrs, err := r.lookupSRV(ctx, service, proto, name) + if err != nil { + return "", nil, err + } + if cname != "" && !isDomainName(cname) { + return "", nil, &DNSError{Err: "SRV header name is invalid", Name: name} + } + for _, addr := range addrs { + if addr == nil { + continue + } + if !isDomainName(addr.Target) { + return "", nil, &DNSError{Err: "SRV target is invalid", Name: name} + } + } + return cname, addrs, nil } // LookupMX returns the DNS MX records for the given domain name sorted by preference. +// +// The returned mail server names are validated to be properly +// formatted presentation-format domain names. func LookupMX(name string) ([]*MX, error) { - return DefaultResolver.lookupMX(context.Background(), name) + return DefaultResolver.LookupMX(context.Background(), name) } // LookupMX returns the DNS MX records for the given domain name sorted by preference. +// +// The returned mail server names are validated to be properly +// formatted presentation-format domain names. func (r *Resolver) LookupMX(ctx context.Context, name string) ([]*MX, error) { - return r.lookupMX(ctx, name) + records, err := r.lookupMX(ctx, name) + if err != nil { + return nil, err + } + for _, mx := range records { + if mx == nil { + continue + } + if !isDomainName(mx.Host) { + return nil, &DNSError{Err: "MX target is invalid", Name: name} + } + } + return records, nil } // LookupNS returns the DNS NS records for the given domain name. +// +// The returned name server names are validated to be properly +// formatted presentation-format domain names. func LookupNS(name string) ([]*NS, error) { - return DefaultResolver.lookupNS(context.Background(), name) + return DefaultResolver.LookupNS(context.Background(), name) } // LookupNS returns the DNS NS records for the given domain name. +// +// The returned name server names are validated to be properly +// formatted presentation-format domain names. func (r *Resolver) LookupNS(ctx context.Context, name string) ([]*NS, error) { - return r.lookupNS(ctx, name) + records, err := r.lookupNS(ctx, name) + if err != nil { + return nil, err + } + for _, ns := range records { + if ns == nil { + continue + } + if !isDomainName(ns.Host) { + return nil, &DNSError{Err: "NS target is invalid", Name: name} + } + } + return records, nil } // LookupTXT returns the DNS TXT records for the given domain name. @@ -466,14 +536,29 @@ func (r *Resolver) LookupTXT(ctx context.Context, name string) ([]string, error) // LookupAddr performs a reverse lookup for the given address, returning a list // of names mapping to that address. // +// The returned names are validated to be properly formatted presentation-format +// domain names. +// // When using the host C library resolver, at most one result will be // returned. To bypass the host resolver, use a custom Resolver. func LookupAddr(addr string) (names []string, err error) { - return DefaultResolver.lookupAddr(context.Background(), addr) + return DefaultResolver.LookupAddr(context.Background(), addr) } // LookupAddr performs a reverse lookup for the given address, returning a list // of names mapping to that address. -func (r *Resolver) LookupAddr(ctx context.Context, addr string) (names []string, err error) { - return r.lookupAddr(ctx, addr) +// +// The returned names are validated to be properly formatted presentation-format +// domain names. +func (r *Resolver) LookupAddr(ctx context.Context, addr string) ([]string, error) { + names, err := r.lookupAddr(ctx, addr) + if err != nil { + return nil, err + } + for _, name := range names { + if !isDomainName(name) { + return nil, &DNSError{Err: "PTR target is invalid", Name: addr} + } + } + return names, nil } -- cgit v1.2.3-54-g00ecf From 895fb1bb6fc0d3c01c5ef7c8cbaf033d1fff9ad7 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Tue, 11 May 2021 11:31:31 -0700 Subject: [release-branch.go1.16] archive/zip: only preallocate File slice if reasonably sized Since the number of files in the EOCD record isn't validated, it isn't safe to preallocate Reader.Files using that field. A malformed archive can indicate it contains up to 1 << 128 - 1 files. We can still safely preallocate the slice by checking if the specified number of files in the archive is reasonable, given the size of the archive. Thanks to the OSS-Fuzz project for discovering this issue and to Emmanuel Odeke for reporting it. Updates #46242 Fixes #46397 Fixes CVE-2021-33196 Change-Id: I3c76d8eec178468b380d87fdb4a3f2cb06f0ee76 Reviewed-on: https://go-review.googlesource.com/c/go/+/318909 Trust: Roland Shoemaker Trust: Katie Hockman Trust: Joe Tsai Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Reviewed-by: Katie Hockman Reviewed-by: Joe Tsai (cherry picked from commit 74242baa4136c7a9132a8ccd9881354442788c8c) Reviewed-on: https://go-review.googlesource.com/c/go/+/322909 Reviewed-by: Filippo Valsorda --- src/archive/zip/reader.go | 10 ++++++- src/archive/zip/reader_test.go | 59 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go index 18f9833db0..ddef2b7b5a 100644 --- a/src/archive/zip/reader.go +++ b/src/archive/zip/reader.go @@ -99,7 +99,15 @@ func (z *Reader) init(r io.ReaderAt, size int64) error { return err } z.r = r - z.File = make([]*File, 0, end.directoryRecords) + // Since the number of directory records is not validated, it is not + // safe to preallocate z.File without first checking that the specified + // number of files is reasonable, since a malformed archive may + // 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 { + z.File = make([]*File, 0, end.directoryRecords) + } z.Comment = end.comment rs := io.NewSectionReader(r, 0, size) if _, err = rs.Seek(int64(end.directoryOffset), io.SeekStart); err != nil { diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go index c6e8d21568..471be27bb1 100644 --- a/src/archive/zip/reader_test.go +++ b/src/archive/zip/reader_test.go @@ -1166,3 +1166,62 @@ func TestCVE202127919(t *testing.T) { t.Errorf("Error reading file: %v", err) } } + +func TestCVE202133196(t *testing.T) { + // Archive that indicates it has 1 << 128 -1 files, + // this would previously cause a panic due to attempting + // to allocate a slice with 1 << 128 -1 elements. + data := []byte{ + 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x08, 0x08, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x02, + 0x03, 0x62, 0x61, 0x65, 0x03, 0x04, 0x00, 0x00, + 0xff, 0xff, 0x50, 0x4b, 0x07, 0x08, 0xbe, 0x20, + 0x5c, 0x6c, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, + 0x14, 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xbe, 0x20, 0x5c, 0x6c, 0x09, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x50, 0x4b, 0x06, 0x06, 0x2c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, + 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x31, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00, + 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, + 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x00, 0x00, + } + _, err := NewReader(bytes.NewReader(data), int64(len(data))) + if err != ErrFormat { + t.Fatalf("unexpected error, got: %v, want: %v", err, ErrFormat) + } + + // Also check that an archive containing a handful of empty + // files doesn't cause an issue + b := bytes.NewBuffer(nil) + w := NewWriter(b) + for i := 0; i < 5; i++ { + _, err := w.Create("") + if err != nil { + t.Fatalf("Writer.Create failed: %s", err) + } + } + if err := w.Close(); err != nil { + t.Fatalf("Writer.Close failed: %s", err) + } + r, err := NewReader(bytes.NewReader(b.Bytes()), int64(b.Len())) + if err != nil { + t.Fatalf("NewReader failed: %s", err) + } + if len(r.File) != 5 { + t.Errorf("Archive has unexpected number of files, got %d, want 5", len(r.File)) + } +} -- cgit v1.2.3-54-g00ecf From 0410005dc458f23fb15f64354f9a24ca8f2fe044 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Fri, 21 May 2021 14:02:30 -0400 Subject: [release-branch.go1.16] net/http/httputil: always remove hop-by-hop headers Previously, we'd fail to remove the Connection header from a request like this: Connection: Connection: x-header Updates #46313 Fixes #46315 Fixes CVE-2021-33197 Change-Id: Ie3009e926ceecfa86dfa6bcc6fe14ff01086be7d Reviewed-on: https://go-review.googlesource.com/c/go/+/321929 Run-TryBot: Filippo Valsorda Reviewed-by: Katie Hockman Trust: Katie Hockman Trust: Filippo Valsorda TryBot-Result: Go Bot (cherry picked from commit 950fa11c4cb01a145bb07eeb167d90a1846061b3) Reviewed-on: https://go-review.googlesource.com/c/go/+/323090 --- src/net/http/httputil/reverseproxy.go | 22 +++++------ src/net/http/httputil/reverseproxy_test.go | 63 +++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go index 4e369580ea..ccb84562e0 100644 --- a/src/net/http/httputil/reverseproxy.go +++ b/src/net/http/httputil/reverseproxy.go @@ -248,22 +248,18 @@ func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) { // important is "Connection" because we want a persistent // connection, regardless of what the client sent to us. for _, h := range hopHeaders { - hv := outreq.Header.Get(h) - if hv == "" { - continue - } - if h == "Te" && hv == "trailers" { - // Issue 21096: tell backend applications that - // care about trailer support that we support - // trailers. (We do, but we don't go out of - // our way to advertise that unless the - // incoming client request thought it was - // worth mentioning) - continue - } outreq.Header.Del(h) } + // Issue 21096: tell backend applications that care about trailer support + // that we support trailers. (We do, but we don't go out of our way to + // advertise that unless the incoming client request thought it was worth + // mentioning.) Note that we look at req.Header, not outreq.Header, since + // the latter has passed through removeConnectionHeaders. + if httpguts.HeaderValuesContainsToken(req.Header["Te"], "trailers") { + outreq.Header.Set("Te", "trailers") + } + // After stripping all the hop-by-hop connection headers above, add back any // necessary for protocol upgrades, such as for websockets. if reqUpType != "" { diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go index 3acbd940e4..3211463bcb 100644 --- a/src/net/http/httputil/reverseproxy_test.go +++ b/src/net/http/httputil/reverseproxy_test.go @@ -90,8 +90,9 @@ func TestReverseProxy(t *testing.T) { getReq, _ := http.NewRequest("GET", frontend.URL, nil) getReq.Host = "some-name" - getReq.Header.Set("Connection", "close") - getReq.Header.Set("Te", "trailers") + getReq.Header.Set("Connection", "close, TE") + getReq.Header.Add("Te", "foo") + getReq.Header.Add("Te", "bar, trailers") getReq.Header.Set("Proxy-Connection", "should be deleted") getReq.Header.Set("Upgrade", "foo") getReq.Close = true @@ -235,6 +236,64 @@ func TestReverseProxyStripHeadersPresentInConnection(t *testing.T) { } } +func TestReverseProxyStripEmptyConnection(t *testing.T) { + // See Issue 46313. + const backendResponse = "I am the backend" + + // someConnHeader is some arbitrary header to be declared as a hop-by-hop header + // in the Request's Connection header. + const someConnHeader = "X-Some-Conn-Header" + + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if c := r.Header.Values("Connection"); len(c) != 0 { + t.Errorf("handler got header %q = %v; want empty", "Connection", c) + } + if c := r.Header.Get(someConnHeader); c != "" { + t.Errorf("handler got header %q = %q; want empty", someConnHeader, c) + } + w.Header().Add("Connection", "") + w.Header().Add("Connection", someConnHeader) + w.Header().Set(someConnHeader, "should be deleted") + io.WriteString(w, backendResponse) + })) + defer backend.Close() + backendURL, err := url.Parse(backend.URL) + if err != nil { + t.Fatal(err) + } + proxyHandler := NewSingleHostReverseProxy(backendURL) + frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + proxyHandler.ServeHTTP(w, r) + if c := r.Header.Get(someConnHeader); c != "should be deleted" { + t.Errorf("handler modified header %q = %q; want %q", someConnHeader, c, "should be deleted") + } + })) + defer frontend.Close() + + getReq, _ := http.NewRequest("GET", frontend.URL, nil) + getReq.Header.Add("Connection", "") + getReq.Header.Add("Connection", someConnHeader) + getReq.Header.Set(someConnHeader, "should be deleted") + res, err := frontend.Client().Do(getReq) + if err != nil { + t.Fatalf("Get: %v", err) + } + defer res.Body.Close() + bodyBytes, err := io.ReadAll(res.Body) + if err != nil { + t.Fatalf("reading body: %v", err) + } + if got, want := string(bodyBytes), backendResponse; got != want { + t.Errorf("got body %q; want %q", got, want) + } + if c := res.Header.Get("Connection"); c != "" { + t.Errorf("handler got header %q = %q; want empty", "Connection", c) + } + if c := res.Header.Get(someConnHeader); c != "" { + t.Errorf("handler got header %q = %q; want empty", someConnHeader, c) + } +} + func TestXForwardedFor(t *testing.T) { const prevForwardedFor = "client ip" const backendResponse = "I am the backend" -- cgit v1.2.3-54-g00ecf From 1613be84815e34b2c803694ac073b2ae67f18168 Mon Sep 17 00:00:00 2001 From: Michael Fraenkel Date: Thu, 13 May 2021 09:41:45 -0600 Subject: [release-branch.go1.16] net/http: prevent infinite wait during TestMissingStatusNoPanic If the client request never makes it to the server, the outstanding accept is never broken. Change the test to always close the listening socket when the client request completes. Updates #45358 Change-Id: I744a91dfa11704e7e528163d7669c394e90456dc Reviewed-on: https://go-review.googlesource.com/c/go/+/319275 Trust: Heschi Kreinick Reviewed-by: Bryan C. Mills (cherry picked from commit c0a7ecfae775a9d50d338e8123fac32a5d04308c) Reviewed-on: https://go-review.googlesource.com/c/go/+/320190 Reviewed-by: Damien Neil Run-TryBot: Bryan C. Mills TryBot-Result: Go Bot --- src/net/http/transport_test.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go index ba85a61683..73d259dc9a 100644 --- a/src/net/http/transport_test.go +++ b/src/net/http/transport_test.go @@ -5314,7 +5314,6 @@ func TestMissingStatusNoPanic(t *testing.T) { ln := newLocalListener(t) addr := ln.Addr().String() - shutdown := make(chan bool, 1) done := make(chan bool) fullAddrURL := fmt.Sprintf("http://%s", addr) raw := "HTTP/1.1 400\r\n" + @@ -5326,10 +5325,7 @@ func TestMissingStatusNoPanic(t *testing.T) { "Aloha Olaa" go func() { - defer func() { - ln.Close() - close(done) - }() + defer close(done) conn, _ := ln.Accept() if conn != nil { @@ -5360,7 +5356,7 @@ func TestMissingStatusNoPanic(t *testing.T) { t.Errorf("got=%v want=%q", err, want) } - close(shutdown) + ln.Close() <-done } -- cgit v1.2.3-54-g00ecf From 40b97d69218c5f31cf444a5dd1883799f94d9ffa Mon Sep 17 00:00:00 2001 From: Lynn Boger Date: Thu, 29 Apr 2021 16:07:25 -0500 Subject: [release-branch.go1.16] cmd/link/internal: fix use of DynlinkingGo with ppc64le trampolines When creating programs with large text sections on ppc64le, trampolines are needed for calls that are too far; however they are not created if the code is generated such that the TOC register r2 is initialized and maintained in the code because then the external linker can create the trampolines. Previously the function DynlinkingGo was used to determine this but in the case where plugins are used, this could return true even though r2 is not valid. To fix this problem I've added a new function r2Valid which returns true when the build options indicate that the r2 is initialized and maintained. Because of the ways that DynlinkingGo is used I wanted to maintain its previous behavior. Fixes #45927 Change-Id: I6d902eba6ad41757aa6474948b79acdbd479cb38 Reviewed-on: https://go-review.googlesource.com/c/go/+/315289 Trust: Lynn Boger Run-TryBot: Lynn Boger Reviewed-by: Cherry Zhang TryBot-Result: Go Bot (cherry picked from commit 9ed736ac2a99aa2e7ef7d8bed3b01ca8b20a6f80) Reviewed-on: https://go-review.googlesource.com/c/go/+/316750 Run-TryBot: Dmitri Shuralyov Reviewed-by: Cherry Mui --- src/cmd/link/internal/ppc64/asm.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go index 602f0b5299..539afac187 100644 --- a/src/cmd/link/internal/ppc64/asm.go +++ b/src/cmd/link/internal/ppc64/asm.go @@ -642,6 +642,16 @@ func archrelocaddr(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r l return int64(o2)<<32 | int64(o1) } +// Determine if the code was compiled so that the TOC register R2 is initialized and maintained +func r2Valid(ctxt *ld.Link) bool { + switch ctxt.BuildMode { + case ld.BuildModeCArchive, ld.BuildModeCShared, ld.BuildModePIE, ld.BuildModeShared, ld.BuildModePlugin: + return true + } + // -linkshared option + return ctxt.IsSharedGoLink() +} + // resolve direct jump relocation r in s, and add trampoline if necessary func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { @@ -649,7 +659,7 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { // For internal linking, trampolines are always created for long calls. // For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in // r2. For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created. - if ctxt.IsExternal() && (ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE) { + if ctxt.IsExternal() && r2Valid(ctxt) { // No trampolines needed since r2 contains the TOC return } @@ -703,7 +713,7 @@ func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) { } } if ldr.SymType(tramp) == 0 { - if ctxt.DynlinkingGo() || ctxt.BuildMode == ld.BuildModeCArchive || ctxt.BuildMode == ld.BuildModeCShared || ctxt.BuildMode == ld.BuildModePIE { + if r2Valid(ctxt) { // Should have returned for above cases ctxt.Errorf(s, "unexpected trampoline for shared or dynamic linking") } else { -- cgit v1.2.3-54-g00ecf From dbf69b7da49b64547ae3a0d54043c0d1f895a0fc Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Mon, 10 May 2021 18:10:18 -0400 Subject: [release-branch.go1.16] cmd/go: in 'go mod download' without args, don't save module zip sums 'go mod download' without arguments is frequently used to populate the module cache. It tends to fetch a lot of extra files (for modules in the build list that aren't needed to build packages in the main module). It's annoying when sums are written for these extra files. 'go mod download mod@version' will still write sums for specific modules in the build list. 'go mod download all' still has the previous behavior. For now, all invocations of 'go mod download' still update go.mod and go.sum with changes needed to load the build list (1.15 behavior). Fixes #46214 Change-Id: I9e17d18a7466ac7271a0e1a2b663f6b3cb168c97 Reviewed-on: https://go-review.googlesource.com/c/go/+/318629 Trust: Jay Conrod Reviewed-by: Bryan C. Mills (cherry picked from commit 4fb10b2118cb16445f2d089f79beb3d32db3db12) Reviewed-on: https://go-review.googlesource.com/c/go/+/321892 Run-TryBot: Jay Conrod TryBot-Result: Go Bot --- src/cmd/go/internal/modcmd/download.go | 32 ++++++++++++++++--- src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt | 2 +- src/cmd/go/testdata/script/mod_download.txt | 36 +++++++++++++++++++--- .../go/testdata/script/mod_get_trailing_slash.txt | 10 ++++-- src/cmd/go/testdata/script/mod_query.txt | 5 +-- src/cmd/go/testdata/script/mod_retract.txt | 8 +++-- 6 files changed, 75 insertions(+), 18 deletions(-) diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go index e7d3d869cb..a602bb9bbe 100644 --- a/src/cmd/go/internal/modcmd/download.go +++ b/src/cmd/go/internal/modcmd/download.go @@ -86,9 +86,11 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { if !modload.HasModRoot() && len(args) == 0 { base.Fatalf("go mod download: no modules specified (see 'go help mod download')") } - if len(args) == 0 { + haveExplicitArgs := len(args) > 0 + if !haveExplicitArgs { args = []string{"all"} - } else if modload.HasModRoot() { + } + if modload.HasModRoot() { modload.LoadModFile(ctx) // to fill Target targetAtUpgrade := modload.Target.Path + "@upgrade" targetAtPatch := modload.Target.Path + "@patch" @@ -137,7 +139,20 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { listRetractions := false type token struct{} sem := make(chan token, runtime.GOMAXPROCS(0)) - for _, info := range modload.ListModules(ctx, args, listU, listVersions, listRetractions) { + infos := modload.ListModules(ctx, args, listU, listVersions, listRetractions) + if !haveExplicitArgs { + // 'go mod download' is sometimes run without arguments to pre-populate + // the module cache. It may fetch modules that aren't needed to build + // packages in the main mdoule. This is usually not intended, so don't save + // sums for downloaded modules (golang.org/issue/45332). + // TODO(golang.org/issue/45551): For now, save sums needed to load the + // build list (same as 1.15 behavior). In the future, report an error if + // go.mod or go.sum need to be updated after loading the build list. + modload.WriteGoMod() + modload.DisallowWriteGoMod() + } + + for _, info := range infos { if info.Replace != nil { info = info.Replace } @@ -187,6 +202,13 @@ func runDownload(ctx context.Context, cmd *base.Command, args []string) { base.ExitIfErrors() } - // Update go.mod and especially go.sum if needed. - modload.WriteGoMod() + // If there were explicit arguments, update go.mod and especially go.sum. + // 'go mod download mod@version' is a useful way to add a sum without using + // 'go get mod@version', which may have other side effects. We print this in + // some error message hints. + // + // Don't save sums for 'go mod download' without arguments; see comment above. + if haveExplicitArgs { + modload.WriteGoMod() + } } diff --git a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt index 00b71bf0d5..7982cccea1 100644 --- a/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt +++ b/src/cmd/go/testdata/mod/rsc.io_sampler_v1.2.1.txt @@ -5,7 +5,7 @@ module "rsc.io/sampler" require "golang.org/x/text" v0.0.0-20170915032832-14c0d48ead0c -- .info -- -{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"}EOF +{"Version":"v1.2.1","Name":"cac3af4f8a0ab40054fa6f8d423108a63a1255bb","Short":"cac3af4f8a0a","Time":"2018-02-13T18:16:22Z"} -- hello.go -- // Copyright 2018 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style diff --git a/src/cmd/go/testdata/script/mod_download.txt b/src/cmd/go/testdata/script/mod_download.txt index 8a9faffe4e..c2b72b2a02 100644 --- a/src/cmd/go/testdata/script/mod_download.txt +++ b/src/cmd/go/testdata/script/mod_download.txt @@ -107,13 +107,28 @@ stderr '^go mod download: skipping argument m that resolves to the main module\n ! go mod download m@latest stderr '^go mod download: m@latest: malformed module path "m": missing dot in first path element$' -# download updates go.mod and populates go.sum +# download without arguments updates go.mod and go.sum after loading the +# build list, but does not save sums for downloaded zips. cd update +cp go.mod.orig go.mod ! exists go.sum go mod download +cmp go.mod.update go.mod +cmp go.sum.update go.sum +cp go.mod.orig go.mod +rm go.sum + +# download with arguments (even "all") does update go.mod and go.sum. +go mod download rsc.io/sampler +cmp go.mod.update go.mod grep '^rsc.io/sampler v1.3.0 ' go.sum -go list -m rsc.io/sampler -stdout '^rsc.io/sampler v1.3.0$' +cp go.mod.orig go.mod +rm go.sum + +go mod download all +cmp go.mod.update go.mod +grep '^rsc.io/sampler v1.3.0 ' go.sum +cd .. # allow go mod download without go.mod env GO111MODULE=auto @@ -131,7 +146,7 @@ stderr 'get '$GOPROXY -- go.mod -- module m --- update/go.mod -- +-- update/go.mod.orig -- module m go 1.16 @@ -140,3 +155,16 @@ require ( rsc.io/quote v1.5.2 rsc.io/sampler v1.2.1 // older version than in build list ) +-- update/go.mod.update -- +module m + +go 1.16 + +require ( + rsc.io/quote v1.5.2 + rsc.io/sampler v1.3.0 // older version than in build list +) +-- update/go.sum.update -- +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt index 3b38d8ba7d..c536693537 100644 --- a/src/cmd/go/testdata/script/mod_get_trailing_slash.txt +++ b/src/cmd/go/testdata/script/mod_get_trailing_slash.txt @@ -1,6 +1,3 @@ -# Populate go.sum -go mod download - # go list should succeed to load a package ending with ".go" if the path does # not correspond to an existing local file. Listing a pattern ending with # ".go/" should try to list a package regardless of whether a file exists at the @@ -31,3 +28,10 @@ module m go 1.13 require example.com/dotgo.go v1.0.0 +-- go.sum -- +example.com/dotgo.go v1.0.0 h1:XKJfs0V8x2PvY2tX8bJBCEbCDLnt15ma2onwhVpew/I= +example.com/dotgo.go v1.0.0/go.mod h1:Qi6z/X3AC5vHiuMt6HF2ICx3KhIBGrMdrA7YoPDKqR0= +-- use.go -- +package use + +import _ "example.com/dotgo.go" diff --git a/src/cmd/go/testdata/script/mod_query.txt b/src/cmd/go/testdata/script/mod_query.txt index e10185709d..a75f86ed7c 100644 --- a/src/cmd/go/testdata/script/mod_query.txt +++ b/src/cmd/go/testdata/script/mod_query.txt @@ -1,9 +1,7 @@ env GO111MODULE=on -# Populate go.sum. # TODO(golang.org/issue/41297): we shouldn't need go.sum. None of the commands # below depend on the build list. -go mod download go list -m -versions rsc.io/quote stdout '^rsc.io/quote v1.0.0 v1.1.0 v1.2.0 v1.2.1 v1.3.0 v1.4.0 v1.5.0 v1.5.1 v1.5.2 v1.5.3-pre1$' @@ -36,6 +34,9 @@ stdout 'no matching versions for query ">v1.5.3"' module x require rsc.io/quote v1.0.0 +-- go.sum -- +rsc.io/quote v1.0.0 h1:kQ3IZQzPTiDJxSZI98YaWgxFEhlNdYASHvh+MplbViw= +rsc.io/quote v1.0.0/go.mod h1:v83Ri/njykPcgJltBc/gEkJTmjTsNgtO1Y7vyIK1CQA= -- use.go -- package use diff --git a/src/cmd/go/testdata/script/mod_retract.txt b/src/cmd/go/testdata/script/mod_retract.txt index a52e05bc72..4f95ece8d7 100644 --- a/src/cmd/go/testdata/script/mod_retract.txt +++ b/src/cmd/go/testdata/script/mod_retract.txt @@ -1,8 +1,5 @@ cp go.mod go.mod.orig -# Populate go.sum. -go mod download - # 'go list pkg' does not report an error when a retracted version is used. go list -e -f '{{if .Error}}{{.Error}}{{end}}' ./use ! stdout . @@ -32,6 +29,11 @@ go 1.15 require example.com/retract v1.0.0-bad +-- go.sum -- +example.com/retract v1.0.0-bad h1:liAW69rbtjY67x2CcNzat668L/w+YGgNX3lhJsWIJis= +example.com/retract v1.0.0-bad/go.mod h1:0DvGGofJ9hr1q63cBrOY/jSY52OwhRGA0K47NE80I5Y= +example.com/retract/self/prev v1.1.0 h1:0/8I/GTG+1eJTFeDQ/fUbgrMsVHHyKhh3Z8DSZp1fuA= +example.com/retract/self/prev v1.1.0/go.mod h1:xl2EcklWuZZHVtHWcpzfSJQmnzAGpKZYpA/Wto7SZN4= -- use/use.go -- package use -- cgit v1.2.3-54-g00ecf From c9f27b8d31291cc1051824c108452c2e05c0b79d Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Tue, 27 Apr 2021 02:31:23 -0400 Subject: [release-branch.go1.16] cmd/go: use a real Go version in the go.mod files in TestScript/mod_readonly For some reason, the go.mod file added to this test in CL 147281 lists 'go 1.20' instead of the version that was actually current when the go.mod file was added. That causes the test's behavior to change under lazy loading, because 1.20 is above the threshold to trigger lazy-loading invariants (1.17). This backports CL 314049 to Go 1.16 in order to fix a spurious test failure in a subsequent change. For #46144 Updates #46142 Updates #36460 Change-Id: I92400996cb051ab30e99bfffafd91ff32a1e7087 Reviewed-on: https://go-review.googlesource.com/c/go/+/314049 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills Reviewed-by: Michael Matloob TryBot-Result: Go Bot Reviewed-on: https://go-review.googlesource.com/c/go/+/319670 Reviewed-by: Jay Conrod --- src/cmd/go/testdata/script/mod_readonly.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cmd/go/testdata/script/mod_readonly.txt b/src/cmd/go/testdata/script/mod_readonly.txt index 176be72967..d05ad2a317 100644 --- a/src/cmd/go/testdata/script/mod_readonly.txt +++ b/src/cmd/go/testdata/script/mod_readonly.txt @@ -89,7 +89,7 @@ stderr '^no required module provides package rsc.io/quote; to add it:\n\tgo get -- go.mod -- module m -go 1.20 +go 1.16 -- x.go -- package x @@ -104,7 +104,7 @@ require ( -- go.mod.redundant -- module m -go 1.20 +go 1.16 require ( rsc.io/quote v1.5.2 @@ -114,7 +114,7 @@ require ( -- go.mod.indirect -- module m -go 1.20 +go 1.16 require ( rsc.io/quote v1.5.2 // indirect @@ -124,7 +124,7 @@ require ( -- go.mod.untidy -- module m -go 1.20 +go 1.16 require ( rsc.io/sampler v1.3.0 // indirect -- cgit v1.2.3-54-g00ecf From f2222d8284fec442da68c6b09f0dabad97ec17c3 Mon Sep 17 00:00:00 2001 From: "Bryan C. Mills" Date: Thu, 13 May 2021 09:48:40 -0400 Subject: [release-branch.go1.16] cmd/go: error out of 'go mod tidy' if the go version is newer than supported MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This backports the test from CL 319669, but — because of extensive changes to the module loader during the Go 1.17 cycle — the implementation is entirely different. (This implementation is based on the addGoStmt function present in init.go in the 1.16 branch.) Fixes #46144 Updates #46142 Change-Id: Ib7a0a159e53cbe476be6aa9a050add10cc750dec Reviewed-on: https://go-review.googlesource.com/c/go/+/319671 Trust: Bryan C. Mills Run-TryBot: Bryan C. Mills TryBot-Result: Go Bot Reviewed-by: Jay Conrod --- src/cmd/go/internal/modcmd/tidy.go | 2 ++ src/cmd/go/internal/modload/buildlist.go | 30 ++++++++++++++++ src/cmd/go/testdata/script/mod_tidy_too_new.txt | 48 +++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 src/cmd/go/testdata/script/mod_tidy_too_new.txt diff --git a/src/cmd/go/internal/modcmd/tidy.go b/src/cmd/go/internal/modcmd/tidy.go index 8bc9ed50be..67f90b123c 100644 --- a/src/cmd/go/internal/modcmd/tidy.go +++ b/src/cmd/go/internal/modcmd/tidy.go @@ -61,6 +61,8 @@ func runTidy(ctx context.Context, cmd *base.Command, args []string) { modload.ForceUseModules = true modload.RootMode = modload.NeedRoot + modload.CheckTidyVersion(ctx, tidyE) + modload.LoadPackages(ctx, modload.PackageOpts{ Tags: imports.AnyTags(), ResolveMissingImports: true, diff --git a/src/cmd/go/internal/modload/buildlist.go b/src/cmd/go/internal/modload/buildlist.go index 45f220a6ee..0ed985384d 100644 --- a/src/cmd/go/internal/modload/buildlist.go +++ b/src/cmd/go/internal/modload/buildlist.go @@ -11,10 +11,13 @@ import ( "cmd/go/internal/mvs" "context" "fmt" + "go/build" "os" "strings" + "golang.org/x/mod/modfile" "golang.org/x/mod/module" + "golang.org/x/mod/semver" ) // buildList is the list of modules to use for building packages. @@ -226,6 +229,33 @@ func ReloadBuildList() []module.Version { return capVersionSlice(buildList) } +// CheckTidyVersion reports an error to stderr if the Go version indicated by +// the go.mod file is not supported by this version of the 'go' command. +// +// If allowError is false, such an error terminates the program. +func CheckTidyVersion(ctx context.Context, allowError bool) { + LoadModFile(ctx) + if index.goVersionV == "" { + return + } + + tags := build.Default.ReleaseTags + maxGo := tags[len(tags)-1] + if !strings.HasPrefix(maxGo, "go") || !modfile.GoVersionRE.MatchString(maxGo[2:]) { + base.Fatalf("go: unrecognized go version %q", maxGo) + } + max := maxGo[2:] + + if semver.Compare(index.goVersionV, "v"+max) > 0 { + have := index.goVersionV[1:] + if allowError { + fmt.Fprintf(os.Stderr, "go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max) + } else { + base.Fatalf("go mod tidy: go.mod file indicates go %s, but maximum supported version is %s\n", have, max) + } + } +} + // TidyBuildList trims the build list to the minimal requirements needed to // retain the same versions of all packages from the preceding call to // LoadPackages. diff --git a/src/cmd/go/testdata/script/mod_tidy_too_new.txt b/src/cmd/go/testdata/script/mod_tidy_too_new.txt new file mode 100644 index 0000000000..ca3163ec2c --- /dev/null +++ b/src/cmd/go/testdata/script/mod_tidy_too_new.txt @@ -0,0 +1,48 @@ +# https://golang.org/issue/46142: 'go mod tidy' should error out if the version +# in the go.mod file is newer than the most recent supported version. + +cp go.mod go.mod.orig + + +# If the go.mod file specifies an unsupported Go version, 'go mod tidy' should +# refuse to edit it: we don't know what a tidy go.mod file for that version +# would look like. + +! go mod tidy +stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$' +cmp go.mod go.mod.orig + + +# The -e flag should push past the error and edit the file anyway, +# but preserve the too-high version. + +cp go.mod.orig go.mod +go mod tidy -e +stderr 'go mod tidy: go.mod file indicates go 2000.0, but maximum supported version is '$goversion'$' +cmp go.mod go.mod.tidy + + +-- go.mod -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m +-- go.mod.tidy -- +module example.net/from/the/future + +go 2000.0 + +replace example.net/m v0.0.0 => ./m + +require example.net/m v0.0.0 +-- x.go -- +package x + +import "example.net/m" +-- m/go.mod -- +module example.net/m + +go 1.17 +-- m/m.go -- +package m -- cgit v1.2.3-54-g00ecf From 0d6115c352b874f881e60dc7cec99fe6da8263a3 Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Wed, 2 Jun 2021 09:20:22 -0700 Subject: [release-branch.go1.16] net: don't rely on system hosts in TestCVE202133195 Also don't unnecessarily deref the error return. Updates #46504 Fixes #46530 Change-Id: I22d14ac76776f8988fa0774bdcb5fcd801ce0185 Reviewed-on: https://go-review.googlesource.com/c/go/+/324190 Trust: David Chase Trust: Damien Neil Run-TryBot: David Chase TryBot-Result: Go Bot Reviewed-by: Damien Neil (cherry picked from commit dd7ba3ba2c860c40be6d70b63d4a678449cae80f) Reviewed-on: https://go-review.googlesource.com/c/go/+/324332 Run-TryBot: Damien Neil Reviewed-by: Ian Lance Taylor --- src/net/dnsclient_unix_test.go | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index 5d3df49bdf..d51113fc13 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -1897,61 +1897,62 @@ func TestCVE202133195(t *testing.T) { // Change the default resolver to match our manipulated resolver originalDefault := DefaultResolver DefaultResolver = &r - defer func() { - DefaultResolver = originalDefault - }() + defer func() { DefaultResolver = originalDefault }() + // Redirect host file lookups. + defer func(orig string) { testHookHostsPath = orig }(testHookHostsPath) + testHookHostsPath = "testdata/hosts" _, err := r.LookupCNAME(context.Background(), "golang.org") if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("Resolver.LookupCNAME returned unexpected error, got %q, want %q", err, expected) } _, err = LookupCNAME("golang.org") if expected := "lookup golang.org: CNAME target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("LookupCNAME returned unexpected error, got %q, want %q", err, expected) } _, _, err = r.LookupSRV(context.Background(), "target", "tcp", "golang.org") if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected) } _, _, err = LookupSRV("target", "tcp", "golang.org") if expected := "lookup golang.org: SRV target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected) } _, _, err = r.LookupSRV(context.Background(), "hdr", "tcp", "golang.org") if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("Resolver.LookupSRV returned unexpected error, got %q, want %q", err, expected) } _, _, err = LookupSRV("hdr", "tcp", "golang.org") if expected := "lookup golang.org: SRV header name is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("LookupSRV returned unexpected error, got %q, want %q", err, expected) } _, err = r.LookupMX(context.Background(), "golang.org") if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("Resolver.LookupMX returned unexpected error, got %q, want %q", err, expected) } _, err = LookupMX("golang.org") if expected := "lookup golang.org: MX target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupMX returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("LookupMX returned unexpected error, got %q, want %q", err, expected) } _, err = r.LookupNS(context.Background(), "golang.org") if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("Resolver.LookupNS returned unexpected error, got %q, want %q", err, expected) } _, err = LookupNS("golang.org") if expected := "lookup golang.org: NS target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupNS returned unexpected error, got %q, want %q", err.Error(), expected) + t.Errorf("LookupNS returned unexpected error, got %q, want %q", err, expected) } - _, err = r.LookupAddr(context.Background(), "1.2.3.4") - if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected { - t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected) + _, err = r.LookupAddr(context.Background(), "192.0.2.42") + if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected { + t.Errorf("Resolver.LookupAddr returned unexpected error, got %q, want %q", err, expected) } - _, err = LookupAddr("1.2.3.4") - if expected := "lookup 1.2.3.4: PTR target is invalid"; err == nil || err.Error() != expected { - t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err.Error(), expected) + _, err = LookupAddr("192.0.2.42") + if expected := "lookup 192.0.2.42: PTR target is invalid"; err == nil || err.Error() != expected { + t.Errorf("LookupAddr returned unexpected error, got %q, want %q", err, expected) } } -- cgit v1.2.3-54-g00ecf From 7677616a263e8ded606cc8297cb67ddc667a876e Mon Sep 17 00:00:00 2001 From: David Chase Date: Thu, 3 Jun 2021 16:08:00 +0000 Subject: [release-branch.go1.16] go1.16.5 Change-Id: Ibe47050481a01ec434f87db31048981e21fba1c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/324552 Run-TryBot: David Chase Trust: David Chase Reviewed-by: Carlos Amedee TryBot-Result: Go Bot --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 31aab04489..6a0311851f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.16.4 \ No newline at end of file +go1.16.5 \ No newline at end of file -- cgit v1.2.3-54-g00ecf