Merge branch 'el6' into epel7

This commit is contained in:
Jakub Čajka 2018-11-23 14:47:07 +01:00
commit ebf90baf57
26 changed files with 2569 additions and 1344 deletions

44
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.rpm
/go1.1.1.src.tar.gz
/go1.1.2.src.tar.gz
/go1.2.1.src.tar.gz
@ -6,8 +7,49 @@
/go1.3.1.src.tar.gz
/go1.3.2.src.tar.gz
/go1.3.3.src.tar.gz
/go1.3.src.tar.gz
/go1.3beta2.src.tar.gz
/go1.3rc1.src.tar.gz
/go1.3rc2.src.tar.gz
/go1.3.src.tar.gz
/go1.4.1.src.tar.gz
/go1.4.2.src.tar.gz
/go1.4.src.tar.gz
/go1.4beta1.src.tar.gz
/go1.4rc1.src.tar.gz
/go1.4rc2.src.tar.gz
/go1.5beta1.src.tar.gz
/golang-19087:a15f344a9efa-xattrs.tar
/go1.5beta2.src.tar.gz
/go1.5beta3.src.tar.gz
/go1.5rc1.src.tar.gz
/go1.5.src.tar.gz
/go1.5.1.src.tar.gz
/go1.5.2.src.tar.gz
/Mark.Twain-Tom.Sawyer.txt.bz2
/go1.5.3.src.tar.gz
/go1.6rc1.src.tar.gz
/go1.6.src.tar.gz
/go1.6.1.src.tar.gz
/go1.6.2.src.tar.gz
/go1.7rc2.src.tar.gz
/go1.7rc5.src.tar.gz
/go1.7.src.tar.gz
/go1.7.1.src.tar.gz
/go1.7.3.src.tar.gz
/go1.7.4.src.tar.gz
/go1.7.6.src.tar.gz
/go1.8rc3.src.tar.gz
/go1.8.src.tar.gz
/go1.8.1.src.tar.gz
/go1.8.3.src.tar.gz
/go1.9beta2.src.tar.gz
/go1.9.src.tar.gz
/go1.9.1.src.tar.gz
/go1.9.2.src.tar.gz
/go1.9.3.src.tar.gz
/go1.9.4.src.tar.gz
/go1.9.5.src.tar.gz
/go1.9.6.src.tar.gz
/go1.9.7.src.tar.gz
/go1.11.1.src.tar.gz
/go1.11.2.src.tar.gz

View File

@ -0,0 +1,88 @@
From edce31a2904846ae74e3c011f2cf5fddc963459e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20=C4=8Cajka?= <jcajka@redhat.com>
Date: Thu, 22 Mar 2018 12:07:32 +0100
Subject: [PATCH 1/3] Don't use the bundled tzdata at runtime, except for the
internal test suite
---
src/time/internal_test.go | 7 +++++--
src/time/zoneinfo_test.go | 3 ++-
src/time/zoneinfo_unix.go | 2 --
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/time/internal_test.go b/src/time/internal_test.go
index 76d5524124..e81ace5f64 100644
--- a/src/time/internal_test.go
+++ b/src/time/internal_test.go
@@ -4,13 +4,15 @@
package time
+import "runtime"
+
func init() {
// force US/Pacific for time zone tests
ForceUSPacificForTesting()
}
func initTestingZone() {
- z, err := loadLocation("America/Los_Angeles", zoneSources[len(zoneSources)-1:])
+ z, err := loadLocation("America/Los_Angeles", zoneSources)
if err != nil {
panic("cannot load America/Los_Angeles for testing: " + err.Error())
}
@@ -21,8 +23,9 @@ func initTestingZone() {
var OrigZoneSources = zoneSources
func forceZipFileForTesting(zipOnly bool) {
- zoneSources = make([]string, len(OrigZoneSources))
+ zoneSources = make([]string, len(OrigZoneSources)+1)
copy(zoneSources, OrigZoneSources)
+ zoneSources = append(zoneSources, runtime.GOROOT()+"/lib/time/zoneinfo.zip")
if zipOnly {
zoneSources = zoneSources[len(zoneSources)-1:]
}
diff --git a/src/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
index 7a55d4f618..6063ca1195 100644
--- a/src/time/zoneinfo_test.go
+++ b/src/time/zoneinfo_test.go
@@ -8,6 +8,7 @@ import (
"fmt"
"os"
"reflect"
+ "runtime"
"testing"
"time"
)
@@ -128,7 +129,7 @@ func TestLoadLocationFromTZData(t *testing.T) {
t.Fatal(err)
}
- tzinfo, err := time.LoadTzinfo(locationName, time.OrigZoneSources[len(time.OrigZoneSources)-1])
+ tzinfo, err := time.LoadTzinfo(locationName, runtime.GOROOT()+"/lib/time/zoneinfo.zip")
if err != nil {
t.Fatal(err)
}
diff --git a/src/time/zoneinfo_unix.go b/src/time/zoneinfo_unix.go
index 88313aa0ed..d9596115ef 100644
--- a/src/time/zoneinfo_unix.go
+++ b/src/time/zoneinfo_unix.go
@@ -12,7 +12,6 @@
package time
import (
- "runtime"
"syscall"
)
@@ -22,7 +21,6 @@ var zoneSources = []string{
"/usr/share/zoneinfo/",
"/usr/share/lib/zoneinfo/",
"/usr/lib/locale/TZ/",
- runtime.GOROOT() + "/lib/time/zoneinfo.zip",
}
func initLocal() {
--
2.14.3

View File

@ -0,0 +1,41 @@
From 817407fc2d6a861e65086388766f58082d38bc0b Mon Sep 17 00:00:00 2001
From: Michael Munday <munday@ca.ibm.com>
Date: Tue, 17 Jan 2017 11:33:38 -0500
Subject: [PATCH 2/3] syscall: expose IfInfomsg.X__ifi_pad on s390x
Exposing this field on s390x improves compatibility with the other
linux architectures, all of which already expose it.
Fixes #18628 and updates #18632.
Change-Id: I08e8e1eb705f898cd8822f8bee0d61ce11d514b5
---
src/syscall/ztypes_linux_s390x.go | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/syscall/ztypes_linux_s390x.go b/src/syscall/ztypes_linux_s390x.go
index 63c4a83b19..b5894255df 100644
--- a/src/syscall/ztypes_linux_s390x.go
+++ b/src/syscall/ztypes_linux_s390x.go
@@ -449,12 +449,12 @@ type RtAttr struct {
}
type IfInfomsg struct {
- Family uint8
- _ uint8
- Type uint16
- Index int32
- Flags uint32
- Change uint32
+ Family uint8
+ X__ifi_pad uint8
+ Type uint16
+ Index int32
+ Flags uint32
+ Change uint32
}
type IfAddrmsg struct {
--
2.14.3

View File

@ -0,0 +1,135 @@
commit 117ddcb83d7f42d6aa72241240af99ded81118e9
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Tue Jun 30 09:22:41 2015 -0700
net/textproto: don't treat spaces as hyphens in header keys
This was originally done in https://codereview.appspot.com/5690059
(Feb 2012) to deal with bad response headers coming back from webcams,
but it presents a potential security problem with HTTP request
smuggling for request headers containing "Content Length" instead of
"Content-Length".
Part of overall HTTP hardening for request smuggling. See RFC 7230.
Thanks to Régis Leroy for the report.
Change-Id: I92b17fb637c9171c5774ea1437979ae2c17ca88a
Reviewed-on: https://go-review.googlesource.com/11772
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/net/http/header.go b/src/net/http/header.go
index 153b943..d847b13 100644
--- a/src/net/http/header.go
+++ b/src/net/http/header.go
@@ -168,6 +168,8 @@ func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error {
// letter and any letter following a hyphen to upper case;
// the rest are converted to lowercase. For example, the
// canonical key for "accept-encoding" is "Accept-Encoding".
+// If s contains a space or invalid header field bytes, it is
+// returned without modifications.
func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) }
// hasToken reports whether token appears with v, ASCII
diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
index e4b8f6b..91303fe 100644
--- a/src/net/textproto/reader.go
+++ b/src/net/textproto/reader.go
@@ -547,11 +547,16 @@ func (r *Reader) upcomingHeaderNewlines() (n int) {
// the rest are converted to lowercase. For example, the
// canonical key for "accept-encoding" is "Accept-Encoding".
// MIME header keys are assumed to be ASCII only.
+// If s contains a space or invalid header field bytes, it is
+// returned without modifications.
func CanonicalMIMEHeaderKey(s string) string {
// Quick check for canonical encoding.
upper := true
for i := 0; i < len(s); i++ {
c := s[i]
+ if !validHeaderFieldByte(c) {
+ return s
+ }
if upper && 'a' <= c && c <= 'z' {
return canonicalMIMEHeaderKey([]byte(s))
}
@@ -565,19 +570,44 @@ func CanonicalMIMEHeaderKey(s string) string {
const toLower = 'a' - 'A'
+// validHeaderFieldByte reports whether b is a valid byte in a header
+// field key. This is actually stricter than RFC 7230, which says:
+// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
+// "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
+// token = 1*tchar
+// TODO: revisit in Go 1.6+ and possibly expand this. But note that many
+// servers have historically dropped '_' to prevent ambiguities when mapping
+// to CGI environment variables.
+func validHeaderFieldByte(b byte) bool {
+ return ('A' <= b && b <= 'Z') ||
+ ('a' <= b && b <= 'z') ||
+ ('0' <= b && b <= '9') ||
+ b == '-'
+}
+
// canonicalMIMEHeaderKey is like CanonicalMIMEHeaderKey but is
// allowed to mutate the provided byte slice before returning the
// string.
+//
+// For invalid inputs (if a contains spaces or non-token bytes), a
+// is unchanged and a string copy is returned.
func canonicalMIMEHeaderKey(a []byte) string {
+ // See if a looks like a header key. If not, return it unchanged.
+ for _, c := range a {
+ if validHeaderFieldByte(c) {
+ continue
+ }
+ // Don't canonicalize.
+ return string(a)
+ }
+
upper := true
for i, c := range a {
// Canonicalize: first letter upper case
// and upper case after each dash.
// (Host, User-Agent, If-Modified-Since).
// MIME headers are ASCII only, so no Unicode issues.
- if c == ' ' {
- c = '-'
- } else if upper && 'a' <= c && c <= 'z' {
+ if upper && 'a' <= c && c <= 'z' {
c -= toLower
} else if !upper && 'A' <= c && c <= 'Z' {
c += toLower
diff --git a/src/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
index 6bbd993..8fce7dd 100644
--- a/src/net/textproto/reader_test.go
+++ b/src/net/textproto/reader_test.go
@@ -24,11 +24,14 @@ var canonicalHeaderKeyTests = []canonicalHeaderKeyTest{
{"uSER-aGENT", "User-Agent"},
{"user-agent", "User-Agent"},
{"USER-AGENT", "User-Agent"},
- {"üser-agenT", "üser-Agent"}, // non-ASCII unchanged
+
+ // Non-ASCII or anything with spaces or non-token chars is unchanged:
+ {"üser-agenT", "üser-agenT"},
+ {"a B", "a B"},
// This caused a panic due to mishandling of a space:
- {"C Ontent-Transfer-Encoding", "C-Ontent-Transfer-Encoding"},
- {"foo bar", "Foo-Bar"},
+ {"C Ontent-Transfer-Encoding", "C Ontent-Transfer-Encoding"},
+ {"foo bar", "foo bar"},
}
func TestCanonicalMIMEHeaderKey(t *testing.T) {
@@ -194,7 +197,7 @@ func TestReadMIMEHeaderNonCompliant(t *testing.T) {
"Foo": {"bar"},
"Content-Language": {"en"},
"Sid": {"0"},
- "Audio-Mode": {"None"},
+ "Audio Mode": {"None"},
"Privilege": {"127"},
}
if !reflect.DeepEqual(m, want) || err != nil {

View File

@ -0,0 +1,112 @@
commit 143822585e32449860e624cace9d2e521deee62e
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Tue Jul 7 13:19:44 2015 -0600
net/http: revert overly-strict part of earlier smuggling defense
The recent https://golang.org/cl/11810 is reportedly a bit too
aggressive.
Apparently some HTTP requests in the wild do contain both a
Transfer-Encoding along with a bogus Content-Length. Instead of
returning a 400 Bad Request error, we should just ignore the
Content-Length like we did before.
Change-Id: I0001be90d09f8293a34f04691f608342875ff5c4
Reviewed-on: https://go-review.googlesource.com/11962
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/net/http/readrequest_test.go b/src/net/http/readrequest_test.go
index 1a3cf91..60e2be4 100644
--- a/src/net/http/readrequest_test.go
+++ b/src/net/http/readrequest_test.go
@@ -178,6 +178,36 @@ var reqTests = []reqTest{
noError,
},
+ // Tests chunked body and a bogus Content-Length which should be deleted.
+ {
+ "POST / HTTP/1.1\r\n" +
+ "Host: foo.com\r\n" +
+ "Transfer-Encoding: chunked\r\n" +
+ "Content-Length: 9999\r\n\r\n" + // to be removed.
+ "3\r\nfoo\r\n" +
+ "3\r\nbar\r\n" +
+ "0\r\n" +
+ "\r\n",
+ &Request{
+ Method: "POST",
+ URL: &url.URL{
+ Path: "/",
+ },
+ TransferEncoding: []string{"chunked"},
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Header: Header{},
+ ContentLength: -1,
+ Host: "foo.com",
+ RequestURI: "/",
+ },
+
+ "foobar",
+ noTrailer,
+ noError,
+ },
+
// CONNECT request with domain name:
{
"CONNECT www.google.com:443 HTTP/1.1\r\n\r\n",
@@ -400,11 +430,6 @@ Content-Length: 3
Content-Length: 4
abc`)},
- {"smuggle_chunked_and_len", reqBytes(`POST / HTTP/1.1
-Transfer-Encoding: chunked
-Content-Length: 3
-
-abc`)},
{"smuggle_content_len_head", reqBytes(`HEAD / HTTP/1.1
Host: foo
Content-Length: 5`)},
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
index 3c868bd..fbbbf24 100644
--- a/src/net/http/transfer.go
+++ b/src/net/http/transfer.go
@@ -430,7 +430,6 @@ func fixTransferEncoding(isResponse bool, requestMethod string, header Header) (
if !present {
return nil, nil
}
- isRequest := !isResponse
delete(header, "Transfer-Encoding")
encodings := strings.Split(raw[0], ",")
@@ -458,12 +457,20 @@ func fixTransferEncoding(isResponse bool, requestMethod string, header Header) (
// RFC 7230 3.3.2 says "A sender MUST NOT send a
// Content-Length header field in any message that
// contains a Transfer-Encoding header field."
- if len(header["Content-Length"]) > 0 {
- if isRequest {
- return nil, errors.New("http: invalid Content-Length with Transfer-Encoding")
- }
- delete(header, "Content-Length")
- }
+ //
+ // but also:
+ // "If a message is received with both a
+ // Transfer-Encoding and a Content-Length header
+ // field, the Transfer-Encoding overrides the
+ // Content-Length. Such a message might indicate an
+ // attempt to perform request smuggling (Section 9.5)
+ // or response splitting (Section 9.4) and ought to be
+ // handled as an error. A sender MUST remove the
+ // received Content-Length field prior to forwarding
+ // such a message downstream."
+ //
+ // Reportedly, these appear in the wild.
+ delete(header, "Content-Length")
return te, nil
}

View File

@ -0,0 +1,225 @@
commit 300d9a21583e7cf0149a778a0611e76ff7c6680f
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Tue Jun 30 14:21:15 2015 -0700
net/http: harden Server against request smuggling
See RFC 7230.
Thanks to Régis Leroy for the report.
Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c
Reviewed-on: https://go-review.googlesource.com/11810
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/src/net/http/readrequest_test.go b/src/net/http/readrequest_test.go
index e930d99..1a3cf91 100644
--- a/src/net/http/readrequest_test.go
+++ b/src/net/http/readrequest_test.go
@@ -9,6 +9,7 @@ import (
"bytes"
"fmt"
"io"
+ "io/ioutil"
"net/url"
"reflect"
"strings"
@@ -323,6 +324,32 @@ var reqTests = []reqTest{
noTrailer,
noError,
},
+
+ // HEAD with Content-Length 0. Make sure this is permitted,
+ // since I think we used to send it.
+ {
+ "HEAD / HTTP/1.1\r\nHost: issue8261.com\r\nConnection: close\r\nContent-Length: 0\r\n\r\n",
+ &Request{
+ Method: "HEAD",
+ URL: &url.URL{
+ Path: "/",
+ },
+ Header: Header{
+ "Connection": []string{"close"},
+ "Content-Length": []string{"0"},
+ },
+ Host: "issue8261.com",
+ Proto: "HTTP/1.1",
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Close: true,
+ RequestURI: "/",
+ },
+
+ noBody,
+ noTrailer,
+ noError,
+ },
}
func TestReadRequest(t *testing.T) {
@@ -356,3 +383,39 @@ func TestReadRequest(t *testing.T) {
}
}
}
+
+// reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters,
+// ending in \r\n\r\n
+func reqBytes(req string) []byte {
+ return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n")
+}
+
+var badRequestTests = []struct {
+ name string
+ req []byte
+}{
+ {"bad_connect_host", reqBytes("CONNECT []%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a HTTP/1.0")},
+ {"smuggle_two_contentlen", reqBytes(`POST / HTTP/1.1
+Content-Length: 3
+Content-Length: 4
+
+abc`)},
+ {"smuggle_chunked_and_len", reqBytes(`POST / HTTP/1.1
+Transfer-Encoding: chunked
+Content-Length: 3
+
+abc`)},
+ {"smuggle_content_len_head", reqBytes(`HEAD / HTTP/1.1
+Host: foo
+Content-Length: 5`)},
+}
+
+func TestReadRequest_Bad(t *testing.T) {
+ for _, tt := range badRequestTests {
+ got, err := ReadRequest(bufio.NewReader(bytes.NewReader(tt.req)))
+ if err == nil {
+ all, err := ioutil.ReadAll(got.Body)
+ t.Errorf("%s: got unexpected request = %#v\n Body = %q, %v", tt.name, got, all, err)
+ }
+ }
+}
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
index 5205003..3887604 100644
--- a/src/net/http/transfer.go
+++ b/src/net/http/transfer.go
@@ -143,6 +143,9 @@ func (t *transferWriter) shouldSendContentLength() bool {
return true
}
if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
+ if t.Method == "GET" || t.Method == "HEAD" {
+ return false
+ }
return true
}
@@ -310,6 +313,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
}
case *Request:
t.Header = rr.Header
+ t.RequestMethod = rr.Method
t.ProtoMajor = rr.ProtoMajor
t.ProtoMinor = rr.ProtoMinor
// Transfer semantics for Requests are exactly like those for
@@ -325,7 +329,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
}
// Transfer encoding, content length
- t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header)
+ t.TransferEncoding, err = fixTransferEncoding(isResponse, t.RequestMethod, t.Header)
if err != nil {
return err
}
@@ -413,12 +417,12 @@ func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
// Sanitize transfer encoding
-func fixTransferEncoding(requestMethod string, header Header) ([]string, error) {
+func fixTransferEncoding(isResponse bool, requestMethod string, header Header) ([]string, error) {
raw, present := header["Transfer-Encoding"]
if !present {
return nil, nil
}
-
+ isRequest := !isResponse
delete(header, "Transfer-Encoding")
encodings := strings.Split(raw[0], ",")
@@ -443,10 +447,15 @@ func fixTransferEncoding(requestMethod string, header Header) ([]string, error)
return nil, &badStringError{"too many transfer encodings", strings.Join(te, ",")}
}
if len(te) > 0 {
- // Chunked encoding trumps Content-Length. See RFC 2616
- // Section 4.4. Currently len(te) > 0 implies chunked
- // encoding.
- delete(header, "Content-Length")
+ // RFC 7230 3.3.2 says "A sender MUST NOT send a
+ // Content-Length header field in any message that
+ // contains a Transfer-Encoding header field."
+ if len(header["Content-Length"]) > 0 {
+ if isRequest {
+ return nil, errors.New("http: invalid Content-Length with Transfer-Encoding")
+ }
+ delete(header, "Content-Length")
+ }
return te, nil
}
@@ -457,9 +466,17 @@ func fixTransferEncoding(requestMethod string, header Header) ([]string, error)
// function is not a method, because ultimately it should be shared by
// ReadResponse and ReadRequest.
func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
-
+ contentLens := header["Content-Length"]
+ isRequest := !isResponse
// Logic based on response type or status
if noBodyExpected(requestMethod) {
+ // For HTTP requests, as part of hardening against request
+ // smuggling (RFC 7230), don't allow a Content-Length header for
+ // methods which don't permit bodies. As an exception, allow
+ // exactly one Content-Length header if its value is "0".
+ if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == "0") {
+ return 0, fmt.Errorf("http: method cannot contain a Content-Length; got %q", contentLens)
+ }
return 0, nil
}
if status/100 == 1 {
@@ -470,13 +487,21 @@ func fixLength(isResponse bool, status int, requestMethod string, header Header,
return 0, nil
}
+ if len(contentLens) > 1 {
+ // harden against HTTP request smuggling. See RFC 7230.
+ return 0, errors.New("http: message cannot contain multiple Content-Length headers")
+ }
+
// Logic based on Transfer-Encoding
if chunked(te) {
return -1, nil
}
// Logic based on Content-Length
- cl := strings.TrimSpace(header.get("Content-Length"))
+ var cl string
+ if len(contentLens) == 1 {
+ cl = strings.TrimSpace(contentLens[0])
+ }
if cl != "" {
n, err := parseContentLength(cl)
if err != nil {
@@ -487,11 +512,14 @@ func fixLength(isResponse bool, status int, requestMethod string, header Header,
header.Del("Content-Length")
}
- if !isResponse && requestMethod == "GET" {
- // RFC 2616 doesn't explicitly permit nor forbid an
+ if !isResponse {
+ // RFC 2616 neither explicitly permits nor forbids an
// entity-body on a GET request so we permit one if
// declared, but we default to 0 here (not -1 below)
// if there's no mention of a body.
+ // Likewise, all other request methods are assumed to have
+ // no body if neither Transfer-Encoding chunked nor a
+ // Content-Length are set.
return 0, nil
}

127
CVE-2017-15041.patch Normal file
View File

@ -0,0 +1,127 @@
diff -up go/src/cmd/go/get.go.cve go/src/cmd/go/get.go
--- go/src/cmd/go/get.go.cve 2017-05-23 20:35:22.000000000 +0200
+++ go/src/cmd/go/get.go 2017-10-10 10:25:24.485047705 +0200
@@ -401,6 +401,11 @@ func downloadPackage(p *Package) error {
p.build.PkgRoot = filepath.Join(list[0], "pkg")
}
root := filepath.Join(p.build.SrcRoot, filepath.FromSlash(rootPath))
+
+ if err := checkNestedVCS(vcs, root, p.build.SrcRoot); err != nil {
+ return err
+ }
+
// If we've considered this repository already, don't do it again.
if downloadRootCache[root] {
return nil
diff -up go/src/cmd/go/go_test.go.cve go/src/cmd/go/go_test.go
--- go/src/cmd/go/go_test.go.cve 2017-05-23 20:35:22.000000000 +0200
+++ go/src/cmd/go/go_test.go 2017-10-10 10:25:24.485047705 +0200
@@ -1235,6 +1235,25 @@ func TestGetGitDefaultBranch(t *testing.
tg.grepStdout(`\* another-branch`, "not on correct default branch")
}
+func TestAccidentalGitCheckout(t *testing.T) {
+ testenv.MustHaveExternalNetwork(t)
+ if _, err := exec.LookPath("git"); err != nil {
+ t.Skip("skipping because git binary not found")
+ }
+
+ tg := testgo(t)
+ defer tg.cleanup()
+ tg.parallel()
+ tg.tempDir("src")
+ tg.setenv("GOPATH", tg.path("."))
+
+ tg.runFail("get", "-u", "vcs-test.golang.org/go/test1-svn-git")
+ tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
+
+ tg.runFail("get", "-u", "vcs-test.golang.org/go/test2-svn-git/test2main")
+ tg.grepStderr("src[\\\\/]vcs-test.* uses git, but parent .*src[\\\\/]vcs-test.* uses svn", "get did not fail for right reason")
+}
+
func TestErrorMessageForSyntaxErrorInTestGoFileSaysFAIL(t *testing.T) {
tg := testgo(t)
defer tg.cleanup()
diff -up go/src/cmd/go/vcs.go.cve go/src/cmd/go/vcs.go
--- go/src/cmd/go/vcs.go.cve 2017-05-23 20:35:22.000000000 +0200
+++ go/src/cmd/go/vcs.go 2017-10-10 10:30:52.151621206 +0200
@@ -479,11 +479,29 @@ func vcsFromDir(dir, srcRoot string) (vc
return nil, "", fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
}
+ var vcsRet *vcsCmd
+ var rootRet string
+
origDir := dir
for len(dir) > len(srcRoot) {
for _, vcs := range vcsList {
if fi, err := os.Stat(filepath.Join(dir, "."+vcs.cmd)); err == nil && fi.IsDir() {
- return vcs, filepath.ToSlash(dir[len(srcRoot)+1:]), nil
+ root := filepath.ToSlash(dir[len(srcRoot)+1:])
+ // Record first VCS we find, but keep looking,
+ // to detect mistakes like one kind of VCS inside another.
+ if vcsRet == nil {
+ vcsRet = vcs
+ rootRet = root
+ continue
+ }
+ // Allow .git inside .git, which can arise due to submodules.
+ if vcsRet == vcs && vcs.cmd == "git" {
+ continue
+ }
+ // Otherwise, we have one VCS inside a different VCS.
+ return nil, "", fmt.Errorf("directory %q uses %s, but parent %q uses %s",
+ filepath.Join(srcRoot, rootRet), vcsRet.cmd, filepath.Join(srcRoot, root), vcs.cmd)
+
}
}
@@ -496,9 +514,48 @@ func vcsFromDir(dir, srcRoot string) (vc
dir = ndir
}
+ if vcsRet != nil {
+ return vcsRet, rootRet, nil
+ }
+
return nil, "", fmt.Errorf("directory %q is not using a known version control system", origDir)
}
+// checkNestedVCS checks for an incorrectly-nested VCS-inside-VCS
+// situation for dir, checking parents up until srcRoot.
+func checkNestedVCS(vcs *vcsCmd, dir, srcRoot string) error {
+ if len(dir) <= len(srcRoot) || dir[len(srcRoot)] != filepath.Separator {
+ return fmt.Errorf("directory %q is outside source root %q", dir, srcRoot)
+ }
+
+ otherDir := dir
+ for len(otherDir) > len(srcRoot) {
+ for _, otherVCS := range vcsList {
+ if _, err := os.Stat(filepath.Join(dir, "."+otherVCS.cmd)); err == nil {
+ // Allow expected vcs in original dir.
+ if otherDir == dir && otherVCS == vcs {
+ continue
+ }
+ // Allow .git inside .git, which can arise due to submodules.
+ if otherVCS == vcs && vcs.cmd == "git" {
+ continue
+ }
+ // Otherwise, we have one VCS inside a different VCS.
+ return fmt.Errorf("directory %q uses %s, but parent %q uses %s", dir, vcs.cmd, otherDir, otherVCS.cmd)
+ }
+ }
+ // Move to parent.
+ newDir := filepath.Dir(otherDir)
+ if len(newDir) >= len(otherDir) {
+ // Shouldn't happen, but just in case, stop.
+ break
+ }
+ otherDir = newDir
+ }
+
+ return nil
+}
+
// repoRoot represents a version control system, a repo, and a root of
// where to put it on disk.
type repoRoot struct {

144
CVE-2017-15042.patch Normal file
View File

@ -0,0 +1,144 @@
From 4be3fc33ef512532b916aa14258087e89eb47347 Mon Sep 17 00:00:00 2001
From: Russ Cox <rsc@golang.org>
Date: Wed, 4 Oct 2017 13:24:49 -0400
Subject: [PATCH] [release-branch.go1.8] net/smtp: fix PlainAuth to refuse to
send passwords to non-TLS servers
PlainAuth originally refused to send passwords to non-TLS servers
and was documented as such.
In 2013, issue #5184 was filed objecting to the TLS requirement,
despite the fact that it is spelled out clearly in RFC 4954.
The only possibly legitimate use case raised was using PLAIN auth
for connections to localhost, and the suggested fix was to let the
server decide: if it advertises that PLAIN auth is OK, believe it.
That approach was adopted in CL 8279043 and released in Go 1.1.
Unfortunately, this is exactly wrong. The whole point of the TLS
requirement is to make sure not to send the password to the wrong
server or to a man-in-the-middle. Instead of implementing this rule,
CL 8279043 blindly trusts the server, so that if a man-in-the-middle
says "it's OK, you can send me your password," PlainAuth does.
And the documentation was not updated to reflect any of this.
This CL restores the original TLS check, as required by RFC 4954
and as promised in the documentation for PlainAuth.
It then carves out a documented exception for connections made
to localhost (defined as "localhost", "127.0.0.1", or "::1").
Cherry-pick of CL 68170.
Change-Id: I1d3729bbd33aa2f11a03f4c000e6bb473164957b
Reviewed-on: https://go-review.googlesource.com/68023
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Chris Broadfoot <cbro@golang.org>
---
src/net/smtp/auth.go | 33 ++++++++++++++++++---------------
src/net/smtp/smtp_test.go | 32 ++++++++++++++++++++++----------
2 files changed, 40 insertions(+), 25 deletions(-)
diff --git a/src/net/smtp/auth.go b/src/net/smtp/auth.go
index 3f1339ebc56..fd1a472f930 100644
--- a/src/net/smtp/auth.go
+++ b/src/net/smtp/auth.go
@@ -44,26 +44,29 @@ type plainAuth struct {
}
// PlainAuth returns an Auth that implements the PLAIN authentication
-// mechanism as defined in RFC 4616.
-// The returned Auth uses the given username and password to authenticate
-// on TLS connections to host and act as identity. Usually identity will be
-// left blank to act as username.
+// mechanism as defined in RFC 4616. The returned Auth uses the given
+// username and password to authenticate to host and act as identity.
+// Usually identity should be the empty string, to act as username.
+//
+// PlainAuth will only send the credentials if the connection is using TLS
+// or is connected to localhost. Otherwise authentication will fail with an
+// error, without sending the credentials.
func PlainAuth(identity, username, password, host string) Auth {
return &plainAuth{identity, username, password, host}
}
+func isLocalhost(name string) bool {
+ return name == "localhost" || name == "127.0.0.1" || name == "::1"
+}
+
func (a *plainAuth) Start(server *ServerInfo) (string, []byte, error) {
- if !server.TLS {
- advertised := false
- for _, mechanism := range server.Auth {
- if mechanism == "PLAIN" {
- advertised = true
- break
- }
- }
- if !advertised {
- return "", nil, errors.New("unencrypted connection")
- }
+ // Must have TLS, or else localhost server.
+ // Note: If TLS is not true, then we can't trust ANYTHING in ServerInfo.
+ // In particular, it doesn't matter if the server advertises PLAIN auth.
+ // That might just be the attacker saying
+ // "it's ok, you can trust me with your password."
+ if !server.TLS && !isLocalhost(server.Name) {
+ return "", nil, errors.New("unencrypted connection")
}
if server.Name != a.host {
return "", nil, errors.New("wrong host name")
diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
index c48fae6d5ac..15eaca524be 100644
--- a/src/net/smtp/smtp_test.go
+++ b/src/net/smtp/smtp_test.go
@@ -60,29 +60,41 @@ testLoop:
}
func TestAuthPlain(t *testing.T) {
- auth := PlainAuth("foo", "bar", "baz", "servername")
tests := []struct {
- server *ServerInfo
- err string
+ authName string
+ server *ServerInfo
+ err string
}{
{
- server: &ServerInfo{Name: "servername", TLS: true},
+ authName: "servername",
+ server: &ServerInfo{Name: "servername", TLS: true},
},
{
- // Okay; explicitly advertised by server.
- server: &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}},
+ // OK to use PlainAuth on localhost without TLS
+ authName: "localhost",
+ server: &ServerInfo{Name: "localhost", TLS: false},
},
{
- server: &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}},
- err: "unencrypted connection",
+ // NOT OK on non-localhost, even if server says PLAIN is OK.
+ // (We don't know that the server is the real server.)
+ authName: "servername",
+ server: &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}},
+ err: "unencrypted connection",
},
{
- server: &ServerInfo{Name: "attacker", TLS: true},
- err: "wrong host name",
+ authName: "servername",
+ server: &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}},
+ err: "unencrypted connection",
+ },
+ {
+ authName: "servername",
+ server: &ServerInfo{Name: "attacker", TLS: true},
+ err: "wrong host name",
},
}
for i, tt := range tests {
+ auth := PlainAuth("foo", "bar", "baz", tt.authName)
_, _, err := auth.Start(tt.server)
got := ""
if err != nil {

7
fedora.go Normal file
View File

@ -0,0 +1,7 @@
// +build rpm_crashtraceback
package runtime
func init() {
setTraceback("crash")
}

View File

@ -1,110 +0,0 @@
# HG changeset patch
# User Cristian Staretu <unclejacksons@gmail.com>
# Date 1405555229 -36000
# Thu Jul 17 10:00:29 2014 +1000
# Node ID 1b17b3426e3c281a973d2d7bbf235b936d6a0942
# Parent 278365dff593f027db6c6b2c0a89262490d6b676
archive/tar: fix writing of pax headers
"archive/tar: reuse temporary buffer in writeHeader" introduced a
change which was supposed to help lower the number of allocations from
512 bytes for every call to writeHeader. This change broke the writing
of PAX headers.
writeHeader calls writePAXHeader and writePAXHeader calls writeHeader
again. writeHeader will end up writing the PAX header twice.
example broken header:
PaxHeaders.4007/NetLock_Arany_=Class_Gold=_Ftanstvny.crt0000000000000000000000000000007112301216634021512 xustar0000000000000000
PaxHeaders.4007/NetLock_Arany_=Class_Gold=_Ftanstvny.crt0000000000000000000000000000007112301216634021512 xustar0000000000000000
example correct header:
PaxHeaders.4290/NetLock_Arany_=Class_Gold=_Ftanstvny.crt0000000000000000000000000000007112301216634021516 xustar0000000000000000
0100644000000000000000000000270412301216634007250 0ustar0000000000000000
This commit adds a dedicated buffer for pax headers to the Writer
struct. This change increases the size of the struct by 512 bytes, but
allows tar/writer to avoid allocating 512 bytes for all written
headers and it avoids allocating 512 more bytes for pax headers.
LGTM=dsymonds
R=dsymonds, dave, iant
CC=golang-codereviews
https://codereview.appspot.com/110480043
Committer: David Symonds <dsymonds@golang.org>
diff -r 278365dff593 -r 1b17b3426e3c src/pkg/archive/tar/writer.go
--- a/src/pkg/archive/tar/writer.go Wed Jul 16 16:29:51 2014 -0700
+++ b/src/pkg/archive/tar/writer.go Thu Jul 17 10:00:29 2014 +1000
@@ -39,7 +39,8 @@
closed bool
usedBinary bool // whether the binary numeric field extension was used
preferPax bool // use pax header instead of binary numeric header
- hdrBuff [blockSize]byte // buffer to use in writeHeader
+ hdrBuff [blockSize]byte // buffer to use in writeHeader when writing a regular header
+ paxHdrBuff [blockSize]byte // buffer to use in writeHeader when writing a pax header
}
// NewWriter creates a new Writer writing to w.
@@ -161,7 +162,17 @@
// subsecond time resolution, but for now let's just capture
// too long fields or non ascii characters
- header := tw.hdrBuff[:]
+ var header []byte
+
+ // We need to select which scratch buffer to use carefully,
+ // since this method is called recursively to write PAX headers.
+ // If allowPax is true, this is the non-recursive call, and we will use hdrBuff.
+ // If allowPax is false, we are being called by writePAXHeader, and hdrBuff is
+ // already being used by the non-recursive call, so we must use paxHdrBuff.
+ header = tw.hdrBuff[:]
+ if !allowPax {
+ header = tw.paxHdrBuff[:]
+ }
copy(header, zeroBlock)
s := slicer(header)
diff -r 278365dff593 -r 1b17b3426e3c src/pkg/archive/tar/writer_test.go
--- a/src/pkg/archive/tar/writer_test.go Wed Jul 16 16:29:51 2014 -0700
+++ b/src/pkg/archive/tar/writer_test.go Thu Jul 17 10:00:29 2014 +1000
@@ -454,3 +454,38 @@
t.Fatal("Couldn't recover long name")
}
}
+
+func TestValidTypeflagWithPAXHeader(t *testing.T) {
+ var buffer bytes.Buffer
+ tw := NewWriter(&buffer)
+
+ fileName := strings.Repeat("ab", 100)
+
+ hdr := &Header{
+ Name: fileName,
+ Size: 4,
+ Typeflag: 0,
+ }
+ if err := tw.WriteHeader(hdr); err != nil {
+ t.Fatalf("Failed to write header: %s", err)
+ }
+ if _, err := tw.Write([]byte("fooo")); err != nil {
+ t.Fatalf("Failed to write the file's data: %s", err)
+ }
+ tw.Close()
+
+ tr := NewReader(&buffer)
+
+ for {
+ header, err := tr.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ t.Fatalf("Failed to read header: %s", err)
+ }
+ if header.Typeflag != 0 {
+ t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag)
+ }
+ }
+}

View File

@ -1,64 +0,0 @@
# HG changeset patch
# User Cristian Staretu <unclejacksons@gmail.com>
# Date 1404344479 -36000
# Thu Jul 03 09:41:19 2014 +1000
# Node ID 17404efd6b02d4b3acd17070e3f89de97a145877
# Parent 837348e418f33fc7a242f56dbe2feff829532526
archive/tar: reuse temporary buffer in readHeader
A temporary 512 bytes buffer is allocated for every call to
readHeader. This buffer isn't returned to the caller and it could
be reused to lower the number of memory allocations.
This CL improves it by using a pool and zeroing out the buffer before
putting it back into the pool.
benchmark old ns/op new ns/op delta
BenchmarkListFiles100k 545249903 538832687 -1.18%
benchmark old allocs new allocs delta
BenchmarkListFiles100k 2105167 2005692 -4.73%
benchmark old bytes new bytes delta
BenchmarkListFiles100k 105903472 54831527 -48.22%
This improvement is very important if your code has to deal with a lot
of tarballs which contain a lot of files.
LGTM=dsymonds
R=golang-codereviews, dave, dsymonds, bradfitz
CC=golang-codereviews
https://codereview.appspot.com/108240044
Committer: David Symonds <dsymonds@golang.org>
diff -r 837348e418f3 -r 17404efd6b02 src/pkg/archive/tar/reader.go
--- a/src/pkg/archive/tar/reader.go Thu Jul 03 09:40:53 2014 +1000
+++ b/src/pkg/archive/tar/reader.go Thu Jul 03 09:41:19 2014 +1000
@@ -29,10 +29,11 @@
// The Next method advances to the next file in the archive (including the first),
// and then it can be treated as an io.Reader to access the file's data.
type Reader struct {
- r io.Reader
- err error
- pad int64 // amount of padding (ignored) after current file entry
- curr numBytesReader // reader for current file entry
+ r io.Reader
+ err error
+ pad int64 // amount of padding (ignored) after current file entry
+ curr numBytesReader // reader for current file entry
+ hdrBuff [blockSize]byte // buffer to use in readHeader
}
// A numBytesReader is an io.Reader with a numBytes method, returning the number
@@ -426,7 +427,9 @@
}
func (tr *Reader) readHeader() *Header {
- header := make([]byte, blockSize)
+ header := tr.hdrBuff[:]
+ copy(header, zeroBlock)
+
if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
return nil
}

View File

@ -1,56 +0,0 @@
# HG changeset patch
# User Cristian Staretu <unclejacksons@gmail.com>
# Date 1404344453 -36000
# Thu Jul 03 09:40:53 2014 +1000
# Node ID 837348e418f33fc7a242f56dbe2feff829532526
# Parent c5f72a685e256457a0872f6587e2bb9500eac7c4
archive/tar: reuse temporary buffer in writeHeader
A temporary 512 bytes buffer is allocated for every call to
writeHeader. This buffer could be reused the lower the number
of memory allocations.
benchmark old ns/op new ns/op delta
BenchmarkWriteFiles100k 634622051 583810847 -8.01%
benchmark old allocs new allocs delta
BenchmarkWriteFiles100k 2701920 2602621 -3.68%
benchmark old bytes new bytes delta
BenchmarkWriteFiles100k 115383884 64349922 -44.23%
This change is very important if your code has to write a lot of
tarballs with a lot of files.
LGTM=dsymonds
R=golang-codereviews, dave, dsymonds
CC=golang-codereviews
https://codereview.appspot.com/107440043
Committer: David Symonds <dsymonds@golang.org>
diff -r c5f72a685e25 -r 837348e418f3 src/pkg/archive/tar/writer.go
--- a/src/pkg/archive/tar/writer.go Wed Jul 02 15:28:57 2014 -0700
+++ b/src/pkg/archive/tar/writer.go Thu Jul 03 09:40:53 2014 +1000
@@ -37,8 +37,9 @@
nb int64 // number of unwritten bytes for current file entry
pad int64 // amount of padding to write after current file entry
closed bool
- usedBinary bool // whether the binary numeric field extension was used
- preferPax bool // use pax header instead of binary numeric header
+ usedBinary bool // whether the binary numeric field extension was used
+ preferPax bool // use pax header instead of binary numeric header
+ hdrBuff [blockSize]byte // buffer to use in writeHeader
}
// NewWriter creates a new Writer writing to w.
@@ -160,7 +161,8 @@
// subsecond time resolution, but for now let's just capture
// too long fields or non ascii characters
- header := make([]byte, blockSize)
+ header := tw.hdrBuff[:]
+ copy(header, zeroBlock)
s := slicer(header)
// keep a reference to the filename to allow to overwrite it later if we detect that we can use ustar longnames instead of pax

View File

@ -0,0 +1,12 @@
diff -up go/src/runtime/runtime-gdb_test.go.gdb go/src/runtime/runtime-gdb_test.go
--- go/src/runtime/runtime-gdb_test.go.gdb 2016-04-28 10:31:13.005689813 +0200
+++ go/src/runtime/runtime-gdb_test.go 2016-04-28 10:32:12.202935125 +0200
@@ -72,7 +72,7 @@ func main() {
}
`
-func TestGdbPython(t *testing.T) {
+func testGdbPython(t *testing.T) {
checkGdbEnvironment(t)
checkGdbVersion(t)
checkGdbPython(t)

View File

@ -1,19 +0,0 @@
Index: go/include/u.h
===================================================================
--- go.orig/include/u.h
+++ go/include/u.h
@@ -38,10 +38,13 @@ extern "C" {
# define __MAKECONTEXT_V2_SOURCE 1
# endif
#endif
+#if defined __linux__ || defined __GNU__ || defined __GLIBC__
+#define _DEFAULT_SOURCE 1
+#else
#define _BSD_SOURCE 1
#define _NETBSD_SOURCE 1 /* NetBSD */
-#define _DEFAULT_SOURCE 1 /* glibc > 2.19 */
#define _SVID_SOURCE 1
+#endif
#if !defined(__APPLE__) && !defined(__OpenBSD__)
# define _XOPEN_SOURCE 1000
# define _XOPEN_SOURCE_EXTENDED 1

View File

@ -1,197 +0,0 @@
# HG changeset patch
# User Alexander Larsson <alexander.larsson@gmail.com>
# Date 1392282510 -39600
# Node ID a15f344a9efa35ef168c8feaa92a15a1cdc93db5
# Parent 1a32fe60e0798d82bbff6c945001c7f0ba8de5ea
archive/tar: support extended attributes
This adds support for archives with the SCHILY.xattr field in the
pax header. This is what gnu tar and star generate.
Fixes issue 7154.
LGTM=dsymonds
R=golang-codereviews, gobot, dsymonds
CC=golang-codereviews
https://codereview.appspot.com/54570043
Committer: David Symonds <dsymonds@golang.org>
diff -r 1a32fe60e079 -r a15f344a9efa src/pkg/archive/tar/common.go
--- a/src/pkg/archive/tar/common.go Thu Feb 13 03:09:03 2014 -0500
+++ b/src/pkg/archive/tar/common.go Thu Feb 13 20:08:30 2014 +1100
@@ -57,6 +57,7 @@
Devminor int64 // minor number of character or block device
AccessTime time.Time // access time
ChangeTime time.Time // status change time
+ Xattrs map[string]string
}
// File name constants from the tar spec.
@@ -189,6 +190,7 @@
paxSize = "size"
paxUid = "uid"
paxUname = "uname"
+ paxXattr = "SCHILY.xattr."
paxNone = ""
)
diff -r 1a32fe60e079 -r a15f344a9efa src/pkg/archive/tar/reader.go
--- a/src/pkg/archive/tar/reader.go Thu Feb 13 03:09:03 2014 -0500
+++ b/src/pkg/archive/tar/reader.go Thu Feb 13 20:08:30 2014 +1100
@@ -139,8 +139,14 @@
return err
}
hdr.Size = int64(size)
+ default:
+ if strings.HasPrefix(k, paxXattr) {
+ if hdr.Xattrs == nil {
+ hdr.Xattrs = make(map[string]string)
+ }
+ hdr.Xattrs[k[len(paxXattr):]] = v
+ }
}
-
}
return nil
}
diff -r 1a32fe60e079 -r a15f344a9efa src/pkg/archive/tar/reader_test.go
--- a/src/pkg/archive/tar/reader_test.go Thu Feb 13 03:09:03 2014 -0500
+++ b/src/pkg/archive/tar/reader_test.go Thu Feb 13 20:08:30 2014 +1100
@@ -161,6 +161,46 @@
},
},
},
+ {
+ file: "testdata/xattrs.tar",
+ headers: []*Header{
+ {
+ Name: "small.txt",
+ Mode: 0644,
+ Uid: 1000,
+ Gid: 10,
+ Size: 5,
+ ModTime: time.Unix(1386065770, 448252320),
+ Typeflag: '0',
+ Uname: "alex",
+ Gname: "wheel",
+ AccessTime: time.Unix(1389782991, 419875220),
+ ChangeTime: time.Unix(1389782956, 794414986),
+ Xattrs: map[string]string{
+ "user.key": "value",
+ "user.key2": "value2",
+ // Interestingly, selinux encodes the terminating null inside the xattr
+ "security.selinux": "unconfined_u:object_r:default_t:s0\x00",
+ },
+ },
+ {
+ Name: "small2.txt",
+ Mode: 0644,
+ Uid: 1000,
+ Gid: 10,
+ Size: 11,
+ ModTime: time.Unix(1386065770, 449252304),
+ Typeflag: '0',
+ Uname: "alex",
+ Gname: "wheel",
+ AccessTime: time.Unix(1389782991, 419875220),
+ ChangeTime: time.Unix(1386065770, 449252304),
+ Xattrs: map[string]string{
+ "security.selinux": "unconfined_u:object_r:default_t:s0\x00",
+ },
+ },
+ },
+ },
}
func TestReader(t *testing.T) {
@@ -180,7 +220,7 @@
f.Close()
continue testLoop
}
- if *hdr != *header {
+ if !reflect.DeepEqual(*hdr, *header) {
t.Errorf("test %d, entry %d: Incorrect header:\nhave %+v\nwant %+v",
i, j, *hdr, *header)
}
@@ -253,7 +293,7 @@
}
// check the header
- if *hdr != *headers[nread] {
+ if !reflect.DeepEqual(*hdr, *headers[nread]) {
t.Errorf("Incorrect header:\nhave %+v\nwant %+v",
*hdr, headers[nread])
}
diff -r 1a32fe60e079 -r a15f344a9efa src/pkg/archive/tar/writer.go
--- a/src/pkg/archive/tar/writer.go Thu Feb 13 03:09:03 2014 -0500
+++ b/src/pkg/archive/tar/writer.go Thu Feb 13 20:08:30 2014 +1100
@@ -236,6 +236,12 @@
return tw.err
}
+ if allowPax {
+ for k, v := range hdr.Xattrs {
+ paxHeaders[paxXattr+k] = v
+ }
+ }
+
if len(paxHeaders) > 0 {
if !allowPax {
return errInvalidHeader
diff -r 1a32fe60e079 -r a15f344a9efa src/pkg/archive/tar/writer_test.go
--- a/src/pkg/archive/tar/writer_test.go Thu Feb 13 03:09:03 2014 -0500
+++ b/src/pkg/archive/tar/writer_test.go Thu Feb 13 20:08:30 2014 +1100
@@ -10,6 +10,7 @@
"io"
"io/ioutil"
"os"
+ "reflect"
"strings"
"testing"
"testing/iotest"
@@ -338,6 +339,45 @@
}
}
+func TestPaxXattrs(t *testing.T) {
+ xattrs := map[string]string{
+ "user.key": "value",
+ }
+
+ // Create an archive with an xattr
+ fileinfo, err := os.Stat("testdata/small.txt")
+ if err != nil {
+ t.Fatal(err)
+ }
+ hdr, err := FileInfoHeader(fileinfo, "")
+ if err != nil {
+ t.Fatalf("os.Stat: %v", err)
+ }
+ contents := "Kilts"
+ hdr.Xattrs = xattrs
+ var buf bytes.Buffer
+ writer := NewWriter(&buf)
+ if err := writer.WriteHeader(hdr); err != nil {
+ t.Fatal(err)
+ }
+ if _, err = writer.Write([]byte(contents)); err != nil {
+ t.Fatal(err)
+ }
+ if err := writer.Close(); err != nil {
+ t.Fatal(err)
+ }
+ // Test that we can get the xattrs back out of the archive.
+ reader := NewReader(&buf)
+ hdr, err = reader.Next()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !reflect.DeepEqual(hdr.Xattrs, xattrs) {
+ t.Fatalf("xattrs did not survive round trip: got %+v, want %+v",
+ hdr.Xattrs, xattrs)
+ }
+}
+
func TestPAXHeader(t *testing.T) {
medName := strings.Repeat("CD", 50)
longName := strings.Repeat("AB", 100)

View File

@ -1,172 +0,0 @@
Index: go/api/go1.txt
===================================================================
--- go.orig/api/go1.txt
+++ go/api/go1.txt
@@ -412,7 +412,6 @@ pkg crypto/ecdsa, type PublicKey struct,
pkg crypto/ecdsa, type PublicKey struct, embedded elliptic.Curve
pkg crypto/elliptic, func GenerateKey(Curve, io.Reader) ([]uint8, *big.Int, *big.Int, error)
pkg crypto/elliptic, func Marshal(Curve, *big.Int, *big.Int) []uint8
-pkg crypto/elliptic, func P224() Curve
pkg crypto/elliptic, func P256() Curve
pkg crypto/elliptic, func P384() Curve
pkg crypto/elliptic, func P521() Curve
Index: go/src/pkg/crypto/ecdsa/ecdsa_test.go
===================================================================
--- go.orig/src/pkg/crypto/ecdsa/ecdsa_test.go
+++ go/src/pkg/crypto/ecdsa/ecdsa_test.go
@@ -33,7 +33,6 @@ func testKeyGeneration(t *testing.T, c e
}
func TestKeyGeneration(t *testing.T) {
- testKeyGeneration(t, elliptic.P224(), "p224")
if testing.Short() {
return
}
@@ -63,7 +62,6 @@ func testSignAndVerify(t *testing.T, c e
}
func TestSignAndVerify(t *testing.T) {
- testSignAndVerify(t, elliptic.P224(), "p224")
if testing.Short() {
return
}
@@ -129,8 +127,6 @@ func TestVectors(t *testing.T) {
parts := strings.SplitN(line, ",", 2)
switch parts[0] {
- case "P-224":
- pub.Curve = elliptic.P224()
case "P-256":
pub.Curve = elliptic.P256()
case "P-384":
Index: go/src/pkg/crypto/elliptic/bottombits.go
===================================================================
--- /dev/null
+++ go/src/pkg/crypto/elliptic/bottombits.go
@@ -0,0 +1,14 @@
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package elliptic
+
+const bottom12Bits = 0xfff
+const bottom28Bits = 0xfffffff
+
+const two31p3 = 1<<31 + 1<<3
+const two31m3 = 1<<31 - 1<<3
+const two31m15m3 = 1<<31 - 1<<15 - 1<<3
+
Index: go/src/pkg/crypto/elliptic/elliptic.go
===================================================================
--- go.orig/src/pkg/crypto/elliptic/elliptic.go
+++ go/src/pkg/crypto/elliptic/elliptic.go
@@ -326,7 +326,6 @@ var p384 *CurveParams
var p521 *CurveParams
func initAll() {
- initP224()
initP256()
initP384()
initP521()
Index: go/src/pkg/crypto/elliptic/elliptic_test.go
===================================================================
--- go.orig/src/pkg/crypto/elliptic/elliptic_test.go
+++ go/src/pkg/crypto/elliptic/elliptic_test.go
@@ -1,3 +1,5 @@
+// +build ignore
+
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
Index: go/src/pkg/crypto/elliptic/p224.go
===================================================================
--- go.orig/src/pkg/crypto/elliptic/p224.go
+++ go/src/pkg/crypto/elliptic/p224.go
@@ -1,3 +1,5 @@
+// +build ignore
+
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
@@ -183,10 +185,6 @@ func p224Add(out, a, b *p224FieldElement
}
}
-const two31p3 = 1<<31 + 1<<3
-const two31m3 = 1<<31 - 1<<3
-const two31m15m3 = 1<<31 - 1<<15 - 1<<3
-
// p224ZeroModP31 is 0 mod p where bit 31 is set in all limbs so that we can
// subtract smaller amounts without underflow. See the section "Subtraction" in
// [1] for reasoning.
@@ -215,9 +213,6 @@ const two63m35m19 = 1<<63 - 1<<35 - 1<<1
// "Subtraction" in [1] for why.
var p224ZeroModP63 = [8]uint64{two63p35, two63m35, two63m35, two63m35, two63m35m19, two63m35, two63m35, two63m35}
-const bottom12Bits = 0xfff
-const bottom28Bits = 0xfffffff
-
// p224Mul computes *out = a*b
//
// a[i] < 2**29, b[i] < 2**30 (or vice versa)
Index: go/src/pkg/crypto/elliptic/p224_test.go
===================================================================
--- go.orig/src/pkg/crypto/elliptic/p224_test.go
+++ go/src/pkg/crypto/elliptic/p224_test.go
@@ -1,3 +1,5 @@
+// +build ignore
+
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
Index: go/src/pkg/crypto/x509/x509.go
===================================================================
--- go.orig/src/pkg/crypto/x509/x509.go
+++ go/src/pkg/crypto/x509/x509.go
@@ -306,9 +306,6 @@ func getPublicKeyAlgorithmFromOID(oid as
// RFC 5480, 2.1.1.1. Named Curve
//
-// secp224r1 OBJECT IDENTIFIER ::= {
-// iso(1) identified-organization(3) certicom(132) curve(0) 33 }
-//
// secp256r1 OBJECT IDENTIFIER ::= {
// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
// prime(1) 7 }
@@ -321,7 +318,6 @@ func getPublicKeyAlgorithmFromOID(oid as
//
// NB: secp256r1 is equivalent to prime256v1
var (
- oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
@@ -329,8 +325,6 @@ var (
func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
switch {
- case oid.Equal(oidNamedCurveP224):
- return elliptic.P224()
case oid.Equal(oidNamedCurveP256):
return elliptic.P256()
case oid.Equal(oidNamedCurveP384):
@@ -343,8 +337,6 @@ func namedCurveFromOID(oid asn1.ObjectId
func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
switch curve {
- case elliptic.P224():
- return oidNamedCurveP224, true
case elliptic.P256():
return oidNamedCurveP256, true
case elliptic.P384():
@@ -1371,7 +1363,7 @@ func signingParamsForPrivateKey(priv int
pubType = ECDSA
switch priv.Curve {
- case elliptic.P224(), elliptic.P256():
+ case elliptic.P256():
hashFunc = crypto.SHA256
sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
case elliptic.P384():

View File

@ -1,12 +0,0 @@
diff -r 87dea3f5ebe7 src/pkg/runtime/pprof/pprof_test.go
--- a/src/pkg/runtime/pprof/pprof_test.go Fri Nov 29 08:32:31 2013 +1100
+++ b/src/pkg/runtime/pprof/pprof_test.go Fri Jan 24 13:47:42 2014 -0500
@@ -32,7 +32,7 @@
})
}
-func TestCPUProfileMultithreaded(t *testing.T) {
+func testCPUProfileMultithreaded(t *testing.T) {
buf := make([]byte, 100000)
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
testCPUProfile(t, []string{"crc32.ChecksumIEEE", "crc32.Update"}, func() {

View File

@ -1,19 +0,0 @@
Index: go/src/make.bash
===================================================================
--- go.orig/src/make.bash
+++ go/src/make.bash
@@ -161,12 +161,12 @@ if [ "$GOHOSTARCH" != "$GOARCH" -o "$GOH
# CC_FOR_TARGET is recorded as the default compiler for the go tool. When building for the host, however,
# use the host compiler, CC, from `cmd/dist/dist env` instead.
CC=$CC GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH \
- "$GOTOOLDIR"/go_bootstrap install -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
+ "$GOTOOLDIR"/go_bootstrap install -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v -x std
echo
fi
echo "# Building packages and commands for $GOOS/$GOARCH."
-CC=$CC_FOR_TARGET "$GOTOOLDIR"/go_bootstrap install $GO_FLAGS -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v std
+CC=$CC_FOR_TARGET "$GOTOOLDIR"/go_bootstrap install $GO_FLAGS -ccflags "$GO_CCFLAGS" -gcflags "$GO_GCFLAGS" -ldflags "$GO_LDFLAGS" -v -x std
echo
rm -f "$GOTOOLDIR"/go_bootstrap

View File

@ -0,0 +1,309 @@
commit a3156aaa121446c4136927f8c2139fefe05ba82c
Author: Brad Fitzpatrick <bradfitz@golang.org>
Date: Tue Sep 29 14:26:48 2015 -0700
net/http/httptest: change Server to use http.Server.ConnState for accounting
With this CL, httptest.Server now uses connection-level accounting of
outstanding requests instead of ServeHTTP-level accounting. This is
more robust and results in a non-racy shutdown.
This is much easier now that net/http.Server has the ConnState hook.
Fixes #12789
Fixes #12781
Change-Id: I098cf334a6494316acb66cd07df90766df41764b
Reviewed-on: https://go-review.googlesource.com/15151
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/src/net/http/httptest/server.go b/src/net/http/httptest/server.go
index 96eb0ef..e4f680f 100644
--- a/src/net/http/httptest/server.go
+++ b/src/net/http/httptest/server.go
@@ -7,13 +7,17 @@
package httptest
import (
+ "bytes"
"crypto/tls"
"flag"
"fmt"
+ "log"
"net"
"net/http"
"os"
+ "runtime"
"sync"
+ "time"
)
// A Server is an HTTP server listening on a system-chosen port on the
@@ -34,24 +38,10 @@ type Server struct {
// wg counts the number of outstanding HTTP requests on this server.
// Close blocks until all requests are finished.
wg sync.WaitGroup
-}
-
-// historyListener keeps track of all connections that it's ever
-// accepted.
-type historyListener struct {
- net.Listener
- sync.Mutex // protects history
- history []net.Conn
-}
-func (hs *historyListener) Accept() (c net.Conn, err error) {
- c, err = hs.Listener.Accept()
- if err == nil {
- hs.Lock()
- hs.history = append(hs.history, c)
- hs.Unlock()
- }
- return
+ mu sync.Mutex // guards closed and conns
+ closed bool
+ conns map[net.Conn]http.ConnState // except terminal states
}
func newLocalListener() net.Listener {
@@ -103,10 +93,9 @@ func (s *Server) Start() {
if s.URL != "" {
panic("Server already started")
}
- s.Listener = &historyListener{Listener: s.Listener}
s.URL = "http://" + s.Listener.Addr().String()
- s.wrapHandler()
- go s.Config.Serve(s.Listener)
+ s.wrap()
+ s.goServe()
if *serve != "" {
fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
select {}
@@ -134,23 +123,10 @@ func (s *Server) StartTLS() {
if len(s.TLS.Certificates) == 0 {
s.TLS.Certificates = []tls.Certificate{cert}
}
- tlsListener := tls.NewListener(s.Listener, s.TLS)
-
- s.Listener = &historyListener{Listener: tlsListener}
+ s.Listener = tls.NewListener(s.Listener, s.TLS)
s.URL = "https://" + s.Listener.Addr().String()
- s.wrapHandler()
- go s.Config.Serve(s.Listener)
-}
-
-func (s *Server) wrapHandler() {
- h := s.Config.Handler
- if h == nil {
- h = http.DefaultServeMux
- }
- s.Config.Handler = &waitGroupHandler{
- s: s,
- h: h,
- }
+ s.wrap()
+ s.goServe()
}
// NewTLSServer starts and returns a new Server using TLS.
@@ -161,43 +137,139 @@ func NewTLSServer(handler http.Handler) *Server {
return ts
}
+type closeIdleTransport interface {
+ CloseIdleConnections()
+}
+
// Close shuts down the server and blocks until all outstanding
// requests on this server have completed.
func (s *Server) Close() {
- s.Listener.Close()
- s.wg.Wait()
- s.CloseClientConnections()
- if t, ok := http.DefaultTransport.(*http.Transport); ok {
+ s.mu.Lock()
+ if !s.closed {
+ s.closed = true
+ s.Listener.Close()
+ s.Config.SetKeepAlivesEnabled(false)
+ for c, st := range s.conns {
+ if st == http.StateIdle {
+ s.closeConn(c)
+ }
+ }
+ // If this server doesn't shut down in 5 seconds, tell the user why.
+ t := time.AfterFunc(5*time.Second, s.logCloseHangDebugInfo)
+ defer t.Stop()
+ }
+ s.mu.Unlock()
+
+ // Not part of httptest.Server's correctness, but assume most
+ // users of httptest.Server will be using the standard
+ // transport, so help them out and close any idle connections for them.
+ if t, ok := http.DefaultTransport.(closeIdleTransport); ok {
t.CloseIdleConnections()
}
+
+ s.wg.Wait()
}
-// CloseClientConnections closes any currently open HTTP connections
-// to the test Server.
+func (s *Server) logCloseHangDebugInfo() {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ var buf bytes.Buffer
+ buf.WriteString("httptest.Server blocked in Close after 5 seconds, waiting for connections:\n")
+ for c, st := range s.conns {
+ fmt.Fprintf(&buf, " %T %p %v in state %v\n", c, c, c.RemoteAddr(), st)
+ }
+ log.Print(buf.String())
+}
+
+// CloseClientConnections closes any open HTTP connections to the test Server.
func (s *Server) CloseClientConnections() {
- hl, ok := s.Listener.(*historyListener)
- if !ok {
- return
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ for c := range s.conns {
+ s.closeConn(c)
}
- hl.Lock()
- for _, conn := range hl.history {
- conn.Close()
+}
+
+func (s *Server) goServe() {
+ s.wg.Add(1)
+ go func() {
+ defer s.wg.Done()
+ s.Config.Serve(s.Listener)
+ }()
+}
+
+// wrap installs the connection state-tracking hook to know which
+// connections are idle.
+func (s *Server) wrap() {
+ oldHook := s.Config.ConnState
+ s.Config.ConnState = func(c net.Conn, cs http.ConnState) {
+ s.mu.Lock()
+ defer s.mu.Unlock()
+ switch cs {
+ case http.StateNew:
+ s.wg.Add(1)
+ if _, exists := s.conns[c]; exists {
+ panic("invalid state transition")
+ }
+ if s.conns == nil {
+ s.conns = make(map[net.Conn]http.ConnState)
+ }
+ s.conns[c] = cs
+ if s.closed {
+ // Probably just a socket-late-binding dial from
+ // the default transport that lost the race (and
+ // thus this connection is now idle and will
+ // never be used).
+ s.closeConn(c)
+ }
+ case http.StateActive:
+ if oldState, ok := s.conns[c]; ok {
+ if oldState != http.StateNew && oldState != http.StateIdle {
+ panic("invalid state transition")
+ }
+ s.conns[c] = cs
+ }
+ case http.StateIdle:
+ if oldState, ok := s.conns[c]; ok {
+ if oldState != http.StateActive {
+ panic("invalid state transition")
+ }
+ s.conns[c] = cs
+ }
+ if s.closed {
+ s.closeConn(c)
+ }
+ case http.StateHijacked, http.StateClosed:
+ s.forgetConn(c)
+ }
+ if oldHook != nil {
+ oldHook(c, cs)
+ }
}
- hl.Unlock()
}
-// waitGroupHandler wraps a handler, incrementing and decrementing a
-// sync.WaitGroup on each request, to enable Server.Close to block
-// until outstanding requests are finished.
-type waitGroupHandler struct {
- s *Server
- h http.Handler // non-nil
+// closeConn closes c. Except on plan9, which is special. See comment below.
+// s.mu must be held.
+func (s *Server) closeConn(c net.Conn) {
+ if runtime.GOOS == "plan9" {
+ // Go's Plan 9 net package isn't great at unblocking reads when
+ // their underlying TCP connections are closed. Don't trust
+ // that that the ConnState state machine will get to
+ // StateClosed. Instead, just go there directly. Plan 9 may leak
+ // resources if the syscall doesn't end up returning. Oh well.
+ s.forgetConn(c)
+ }
+ go c.Close()
}
-func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- h.s.wg.Add(1)
- defer h.s.wg.Done() // a defer, in case ServeHTTP below panics
- h.h.ServeHTTP(w, r)
+// forgetConn removes c from the set of tracked conns and decrements it from the
+// waitgroup, unless it was previously removed.
+// s.mu must be held.
+func (s *Server) forgetConn(c net.Conn) {
+ if _, ok := s.conns[c]; ok {
+ delete(s.conns, c)
+ s.wg.Done()
+ }
}
// localhostCert is a PEM-encoded TLS cert with SAN IPs
diff --git a/src/net/http/httptest/server_test.go b/src/net/http/httptest/server_test.go
index 500a9f0..90901ce 100644
--- a/src/net/http/httptest/server_test.go
+++ b/src/net/http/httptest/server_test.go
@@ -27,3 +27,30 @@ func TestServer(t *testing.T) {
t.Errorf("got %q, want hello", string(got))
}
}
+
+// Issue 12781
+func TestGetAfterClose(t *testing.T) {
+ ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte("hello"))
+ }))
+
+ res, err := http.Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ got, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(got) != "hello" {
+ t.Fatalf("got %q, want hello", string(got))
+ }
+
+ ts.Close()
+
+ res, err = http.Get(ts.URL)
+ if err == nil {
+ body, _ := ioutil.ReadAll(res.Body)
+ t.Fatalf("Unexected response after close: %v, %v, %s", res.Status, res.Header, body)
+ }
+}

View File

@ -1,11 +0,0 @@
--- src/pkg/os/os_test.go.orig 2014-02-20 13:14:45.543644182 -0600
+++ src/pkg/os/os_test.go 2014-02-20 13:14:55.934813622 -0600
@@ -854,7 +854,7 @@
t.Fatal(err)
}
defer r.Close()
- p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
+ p, err := StartProcess("/usr/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
if err != nil {
t.Fatal(err)
}

View File

@ -1 +1 @@
add-auto-load-safe-path /usr/lib/golang/src/pkg/runtime/runtime-gdb.py
add-auto-load-safe-path /usr/lib/golang/src/runtime/runtime-gdb.py

File diff suppressed because it is too large Load Diff

457
ppc64x-overflow-1.patch Normal file
View File

@ -0,0 +1,457 @@
From d6beea7f9ea1aa2ae5abca7fccb252767820aa13 Mon Sep 17 00:00:00 2001
From: Lynn Boger <laboger@linux.vnet.ibm.com>
Date: Tue, 26 Jul 2016 08:51:10 -0500
Subject: [PATCH] cmd/link: split large elf text sections for ppc64x
Some applications built with Go on ppc64x with
external linking can fail to link with relocation
truncation errors, due to the way that the golang
compiler generates a single go.o file containing
a single large text section to send to the GNU
linker. If the size of the single text section is
greater than 2^26, this can lead to link errors
due to 24 bit offset field in the bl (call)
instruction.
This fix solves the problem by splitting into
multiple text sections when this limit is reached.
When this is done then the GNU linker can fix the
long calls and insert jump tables where needed.
---
src/cmd/link/internal/ld/data.go | 52 +++++++++++++++++++++++++++++--
src/cmd/link/internal/ld/elf.go | 60 ++++++++++++++++++++++++++++++++---
src/cmd/link/internal/ld/lib.go | 20 ++++++++++++
src/cmd/link/internal/ld/symtab.go | 64 ++++++++++++++++++++++++++++++++++++++
src/cmd/link/internal/ppc64/asm.go | 12 ++++---
src/runtime/symtab.go | 34 +++++++++++++++-----
src/runtime/type.go | 16 +++++++++-
7 files changed, 237 insertions(+), 21 deletions(-)
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 57a0dad..58ce18c 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -527,7 +527,15 @@ func relocsym(s *LSym) {
o = Symaddr(r.Sym) + r.Add - int64(r.Sym.Sect.Vaddr)
case obj.R_ADDROFF:
- o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
+
+ // The method offset tables using this relocation expect the offset to be relative
+ // to the start of the first text section, even if there are multiple.
+
+ if Linkmode == LinkExternal && r.Sym.Sect.Name == ".text" && r.Sym.Sect.Vaddr != Segtext.Vaddr {
+ o = Symaddr(r.Sym) - int64(Segtext.Vaddr) + r.Add
+ } else {
+ o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
+ }
// r->sym can be null when CALL $(constant) is transformed from absolute PC to relative PC call.
case obj.R_CALL, obj.R_GOTPCREL, obj.R_PCREL:
@@ -1926,6 +1934,7 @@ func textaddress() {
}
va := uint64(INITTEXT)
sect.Vaddr = va
+ n := 1
for _, sym := range Ctxt.Textp {
sym.Sect = sect
if sym.Type&obj.SSUB != 0 {
@@ -1948,9 +1957,30 @@ func textaddress() {
} else {
va += uint64(sym.Size)
}
+ // On ppc64x a text section should not be larger than 2^26 bytes due to the size of
+ // call target offset field in the bl instruction. Splitting into text
+ // sections smaller than this limit allows the GNU linker to modify the long calls
+ // appropriately. The limit allows for the space for linker tables.
+
+ // Only break at outermost syms.
+
+ if sym.Outer == nil && Iself && Linkmode == LinkExternal && SysArch.InFamily(sys.PPC64) && va-sect.Vaddr > uint64(0x1c00000) {
+
+ // Set the length for the previous text section
+ sect.Length = va - sect.Vaddr
+
+ // Create new section, set the starting Vaddr
+ sect = addsection(&Segtext, ".text", 05)
+ sect.Vaddr = va
+
+ // Create a symbol for the start and end of the secondary text section
+ Linklookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect
+ n++
+ }
}
sect.Length = va - sect.Vaddr
+ Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
}
// assign addresses
@@ -2057,11 +2087,27 @@ func address() {
Segdwarf.Filelen = va - Segdwarf.Vaddr
text := Segtext.Sect
+ lasttext := text
var rodata *Section
if Segrodata.Sect != nil {
rodata = Segrodata.Sect
} else {
- rodata = text.Next
+ // Could be multiple .text sections
+ n := 1
+ for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
+ if sect.Name != ".text" {
+ break
+ }
+ lasttext = sect
+ symname := fmt.Sprintf("runtime.text.%d", n)
+ xdefine(symname, obj.STEXT, int64(sect.Vaddr))
+ n++
+ }
+
+ rodata = lasttext.Next
+ if rodata != nil && rodata.Name != ".rodata" {
+ Diag("Unexpected section order in text segment")
+ }
}
var relrodata *Section
typelink := rodata.Next
@@ -2108,7 +2154,7 @@ func address() {
}
xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
- xdefine("runtime.etext", obj.STEXT, int64(text.Vaddr+text.Length))
+ xdefine("runtime.etext", obj.STEXT, int64(lasttext.Vaddr+lasttext.Length))
if HEADTYPE == obj.Hwindows {
xdefine(".text", obj.STEXT, int64(text.Vaddr))
}
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 39d3609..ecb00c2 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -1623,6 +1623,25 @@ func elfshname(name string) *ElfShdr {
return nil
}
+// Create an ElfShdr for the section with name.
+// A new one is created even if one already exists with
+// the same name.
+func elfshnamedup(name string) *ElfShdr {
+ var off int
+ var sh *ElfShdr
+
+ for i := 0; i < nelfstr; i++ {
+ if name == elfstr[i].s {
+ off = elfstr[i].off
+ sh = newElfShdr(int64(off))
+ return sh
+ }
+ }
+ Diag("cannot find elf name %s", name)
+ errorexit()
+ return nil
+}
+
func elfshalloc(sect *Section) *ElfShdr {
sh := elfshname(sect.Name)
sect.Elfsect = sh
@@ -1630,7 +1649,17 @@ func elfshalloc(sect *Section) *ElfShdr {
}
func elfshbits(sect *Section) *ElfShdr {
- sh := elfshalloc(sect)
+ var sh *ElfShdr
+
+ if sect.Name == ".text" {
+ if sect.Elfsect == nil {
+ sect.Elfsect = elfshnamedup(sect.Name)
+ }
+ sh = sect.Elfsect
+ } else {
+ sh = elfshalloc(sect)
+ }
+
// If this section has already been set up as a note, we assume type_ and
// flags are already correct, but the other fields still need filling in.
if sh.type_ == SHT_NOTE {
@@ -1706,6 +1735,15 @@ func elfshreloc(sect *Section) *ElfShdr {
}
sh := elfshname(elfRelType + sect.Name)
+
+ // There could be multiple text sections but each needs
+ // its own .rela.text.
+ if sect.Name == ".text" {
+ if sh.info != 0 && sh.info != uint32(sect.Elfsect.shnum) {
+ sh = elfshnamedup(elfRelType + sect.Name)
+ }
+ }
+
sh.type_ = uint32(typ)
sh.entsize = uint64(SysArch.RegSize) * 2
if typ == SHT_RELA {
@@ -1776,9 +1814,12 @@ func Elfemitreloc() {
Cput(0)
}
- elfrelocsect(Segtext.Sect, Ctxt.Textp)
- for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
- elfrelocsect(sect, datap)
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ if sect.Name == ".text" {
+ elfrelocsect(sect, Ctxt.Textp)
+ } else {
+ elfrelocsect(sect, datap)
+ }
}
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
elfrelocsect(sect, datap)
@@ -2109,7 +2150,16 @@ func Asmbelfsetup() {
elfshname("")
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
- elfshalloc(sect)
+
+ // There could be multiple .text sections. Instead check the Elfsect
+ // field to determine if already has an ElfShdr and if not, create one.
+ if sect.Name == ".text" {
+ if sect.Elfsect == nil {
+ sect.Elfsect = elfshnamedup(sect.Name)
+ }
+ } else {
+ elfshalloc(sect)
+ }
}
for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
elfshalloc(sect)
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 14f4fa9..709e7ca 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1956,6 +1956,26 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
if s.Type == obj.STEXT {
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
}
+ n := 0
+
+ // Generate base addresses for all text sections if there are multiple
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ if n == 0 {
+ n++
+ continue
+ }
+ if sect.Name != ".text" {
+ break
+ }
+ s = Linkrlookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0)
+ if s == nil {
+ break
+ }
+ if s.Type == obj.STEXT {
+ put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
+ }
+ n++
+ }
s = Linklookup(Ctxt, "runtime.etext", 0)
if s.Type == obj.STEXT {
put(s, s.Name, 'T', s.Value, s.Size, int(s.Version), nil)
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 06d7792..80eb33d 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -315,6 +315,62 @@ func (libs byPkg) Swap(a, b int) {
libs[a], libs[b] = libs[b], libs[a]
}
+// Create a table with information on the text sections.
+
+func textsectionmap() uint32 {
+
+ t := Linklookup(Ctxt, "runtime.textsectionmap", 0)
+ t.Type = obj.SRODATA
+ t.Attr |= AttrReachable
+ nsections := int64(0)
+
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ if sect.Name == ".text" {
+ nsections++
+ } else {
+ break
+ }
+ }
+ Symgrow(Ctxt, t, nsections*3*8)
+
+ off := int64(0)
+ n := 0
+
+ // The vaddr for each text section is the difference between the section's
+ // Vaddr and the Vaddr for the first text section as determined at compile
+ // time.
+
+ // The symbol name for the start address of the first text section is
+ // runtime.text. Additional text sections are named runtime.text.n where n is the
+ // order of creation starting with 1. These symbols provide the section's
+ // start address after relocation by the linker.
+
+ textbase := Segtext.Sect.Vaddr
+ for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ if sect.Name != ".text" {
+ break
+ }
+ off = setuintxx(Ctxt, t, off, sect.Vaddr-textbase, int64(SysArch.IntSize))
+ off = setuintxx(Ctxt, t, off, sect.Length, int64(SysArch.IntSize))
+ if n == 0 {
+ s := Linkrlookup(Ctxt, "runtime.text", 0)
+ if s == nil {
+ Diag("Unable to find symbol runtime.text\n")
+ }
+ off = setaddr(Ctxt, t, off, s)
+
+ } else {
+ s := Linklookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0)
+ if s == nil {
+ Diag("Unable to find symbol runtime.text.%d\n", n)
+ }
+ off = setaddr(Ctxt, t, off, s)
+ }
+ n++
+ }
+ return uint32(n)
+}
+
func symtab() {
dosymtype()
@@ -489,6 +545,8 @@ func symtab() {
adduint(Ctxt, abihashgostr, uint64(hashsym.Size))
}
+ nsections := textsectionmap()
+
// Information about the layout of the executable image for the
// runtime to use. Any changes here must be matched by changes to
// the definition of moduledata in runtime/symtab.go.
@@ -527,6 +585,12 @@ func symtab() {
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.gcbss", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.types", 0))
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.etypes", 0))
+
+ // text section information
+ Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.textsectionmap", 0))
+ adduint(Ctxt, moduledata, uint64(nsections))
+ adduint(Ctxt, moduledata, uint64(nsections))
+
// The typelinks slice
Addaddr(Ctxt, moduledata, Linklookup(Ctxt, "runtime.typelink", 0))
adduint(Ctxt, moduledata, uint64(ntypelinks))
diff --git a/src/cmd/link/internal/ppc64/asm.go b/src/cmd/link/internal/ppc64/asm.go
index bd2e23f..ab59fa8 100644
--- a/src/cmd/link/internal/ppc64/asm.go
+++ b/src/cmd/link/internal/ppc64/asm.go
@@ -813,12 +813,14 @@ func asmb() {
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
- ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for sect := ld.Segtext.Sect; sect != nil; sect = sect.Next {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
- ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ // Might have multiple text sections
+ if sect.Name == ".text" {
+ ld.Codeblk(int64(sect.Vaddr), int64(sect.Length))
+ } else {
+ ld.Datblk(int64(sect.Vaddr), int64(sect.Length))
+ }
}
if ld.Segrodata.Filelen > 0 {
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
index 4f6fae2..23e80ce 100644
--- a/src/runtime/symtab.go
+++ b/src/runtime/symtab.go
@@ -195,8 +195,9 @@ type moduledata struct {
end, gcdata, gcbss uintptr
types, etypes uintptr
- typelinks []int32 // offsets from types
- itablinks []*itab
+ textsectmap []textsect
+ typelinks []int32 // offsets from types
+ itablinks []*itab
modulename string
modulehashes []modulehash
@@ -226,6 +227,14 @@ type functab struct {
funcoff uintptr
}
+// Mapping information for secondary text sections
+
+type textsect struct {
+ vaddr uint64 // prelinked section vaddr
+ length uint64 // section length
+ baseaddr uintptr // relocated section address
+}
+
const minfunc = 16 // minimum function size
const pcbucketsize = 256 * minfunc // size of bucket in the pc->func lookup table
@@ -368,12 +377,23 @@ func findfunc(pc uintptr) *_func {
ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
idx := ffb.idx + uint32(ffb.subbuckets[i])
if pc < datap.ftab[idx].entry {
- throw("findfunc: bad findfunctab entry")
- }
- // linear search to find func with pc >= entry.
- for datap.ftab[idx+1].entry <= pc {
- idx++
+ // If there are multiple text sections then the buckets for the secondary
+ // text sections will be off because the addresses in those text sections
+ // were relocated to higher addresses. Search back to find it.
+
+ for datap.ftab[idx].entry > pc && idx > 0 {
+ idx--
+ }
+ if idx == 0 {
+ throw("findfunc: bad findfunctab entry idx")
+ }
+ } else {
+
+ // linear search to find func with pc >= entry.
+ for datap.ftab[idx+1].entry <= pc {
+ idx++
+ }
}
return (*_func)(unsafe.Pointer(&datap.pclntable[datap.ftab[idx].funcoff]))
}
diff --git a/src/runtime/type.go b/src/runtime/type.go
index 5ef11a4..f641adc 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -257,7 +257,21 @@ func (t *_type) textOff(off textOff) unsafe.Pointer {
}
return res
}
- res := md.text + uintptr(off)
+ res := uintptr(0)
+
+ // Find the text section range that contains the offset to determine the section's base
+ // address. In cases where there are multiple text sections, the base address might be
+ // relocated by the linker.
+
+ for i := 0; i < len(md.textsectmap); i++ {
+ sectaddr := md.textsectmap[i].vaddr
+ sectlen := md.textsectmap[i].length
+ if uint64(off) >= sectaddr && uint64(off) <= sectaddr+sectlen {
+ res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr)
+ break
+ }
+ }
+
if res > md.etext {
println("runtime: textOff", hex(off), "out of range", hex(md.text), "-", hex(md.etext))
throw("runtime: text offset out of range")

150
ppc64x-overflow-2.patch Normal file
View File

@ -0,0 +1,150 @@
From a5b97a846d70cd8db7f33c24f2b9159f935ce318 Mon Sep 17 00:00:00 2001
From: Lynn Boger <laboger@linux.vnet.ibm.com>
Date: Tue, 13 Sep 2016 15:13:08 -0500
Subject: [PATCH] cmd/compile: large text sections on ppc64le
Additional fixes as submitted upstream.
---
src/cmd/link/internal/ld/data.go | 24 ++++++++++++------------
src/cmd/link/internal/ld/lib.go | 2 +-
src/cmd/link/internal/ld/symtab.go | 2 +-
src/runtime/type.go | 28 ++++++++++++++++++----------
4 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index 58ce18c..d8e43ff 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -531,7 +531,7 @@ func relocsym(s *LSym) {
// The method offset tables using this relocation expect the offset to be relative
// to the start of the first text section, even if there are multiple.
- if Linkmode == LinkExternal && r.Sym.Sect.Name == ".text" && r.Sym.Sect.Vaddr != Segtext.Vaddr {
+ if r.Sym.Sect.Name == ".text" {
o = Symaddr(r.Sym) - int64(Segtext.Vaddr) + r.Add
} else {
o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
@@ -1928,7 +1928,6 @@ func textaddress() {
sect.Align = int32(Funcalign)
Linklookup(Ctxt, "runtime.text", 0).Sect = sect
- Linklookup(Ctxt, "runtime.etext", 0).Sect = sect
if HEADTYPE == obj.Hwindows {
Linklookup(Ctxt, ".text", 0).Sect = sect
}
@@ -1964,7 +1963,7 @@ func textaddress() {
// Only break at outermost syms.
- if sym.Outer == nil && Iself && Linkmode == LinkExternal && SysArch.InFamily(sys.PPC64) && va-sect.Vaddr > uint64(0x1c00000) {
+ if sym.Outer == nil && Iself && Linkmode == LinkExternal && SysArch.InFamily(sys.PPC64) && va-sect.Vaddr > 0x1c00000 {
// Set the length for the previous text section
sect.Length = va - sect.Vaddr
@@ -1973,7 +1972,7 @@ func textaddress() {
sect = addsection(&Segtext, ".text", 05)
sect.Vaddr = va
- // Create a symbol for the start and end of the secondary text section
+ // Create a symbol for the start of the secondary text section
Linklookup(Ctxt, fmt.Sprintf("runtime.text.%d", n), 0).Sect = sect
n++
}
@@ -2093,15 +2092,8 @@ func address() {
rodata = Segrodata.Sect
} else {
// Could be multiple .text sections
- n := 1
- for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
- if sect.Name != ".text" {
- break
- }
+ for sect := Segtext.Sect.Next; sect != nil && sect.Name == ".text"; sect = sect.Next {
lasttext = sect
- symname := fmt.Sprintf("runtime.text.%d", n)
- xdefine(symname, obj.STEXT, int64(sect.Vaddr))
- n++
}
rodata = lasttext.Next
@@ -2155,6 +2147,14 @@ func address() {
xdefine("runtime.text", obj.STEXT, int64(text.Vaddr))
xdefine("runtime.etext", obj.STEXT, int64(lasttext.Vaddr+lasttext.Length))
+
+ n := 1
+ for sect := Segtext.Sect.Next; sect != nil && sect.Name == ".text"; sect = sect.Next {
+ symname := fmt.Sprintf("runtime.text.%d", n)
+ xdefine(symname, obj.STEXT, int64(sect.Vaddr))
+ n++
+ }
+
if HEADTYPE == obj.Hwindows {
xdefine(".text", obj.STEXT, int64(text.Vaddr))
}
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 709e7ca..c37ef92 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -1958,7 +1958,7 @@ func genasmsym(put func(*LSym, string, int, int64, int64, int, *LSym)) {
}
n := 0
- // Generate base addresses for all text sections if there are multiple
+ // Generate base addresses for all text sections if there are multiple.
for sect := Segtext.Sect; sect != nil; sect = sect.Next {
if n == 0 {
n++
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index 80eb33d..ec26f88 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -331,7 +331,7 @@ func textsectionmap() uint32 {
break
}
}
- Symgrow(Ctxt, t, nsections*3*8)
+ Symgrow(Ctxt, t, nsections*(2*int64(SysArch.IntSize)+int64(SysArch.PtrSize)))
off := int64(0)
n := 0
diff --git a/src/runtime/type.go b/src/runtime/type.go
index f641adc..d4df5a9 100644
--- a/src/runtime/type.go
+++ b/src/runtime/type.go
@@ -259,17 +259,25 @@ func (t *_type) textOff(off textOff) unsafe.Pointer {
}
res := uintptr(0)
- // Find the text section range that contains the offset to determine the section's base
- // address. In cases where there are multiple text sections, the base address might be
- // relocated by the linker.
-
- for i := 0; i < len(md.textsectmap); i++ {
- sectaddr := md.textsectmap[i].vaddr
- sectlen := md.textsectmap[i].length
- if uint64(off) >= sectaddr && uint64(off) <= sectaddr+sectlen {
- res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr)
- break
+ // The text, or instruction stream is generated as one large buffer. The off (offset) for a method is
+ // its offset within this buffer. If the total text size gets too large, there can be issues on platforms like ppc64 if
+ // the target of calls are too far for the call instruction. To resolve the large text issue, the text is split
+ // into multiple text sections to allow the linker to generate long calls when necessary. When this happens, the vaddr
+ // for each text section is set to its offset within the text. Each method's offset is compared against the section
+ // vaddrs and sizes to determine the containing section. Then the section relative offset is added to the section's
+ // relocated baseaddr to compute the method addess.
+
+ if len(md.textsectmap) > 1 {
+ for i := 0; i < len(md.textsectmap); i++ {
+ sectaddr := md.textsectmap[i].vaddr
+ sectlen := md.textsectmap[i].length
+ if uint64(off) >= sectaddr && uint64(off) <= sectaddr+sectlen {
+ res = md.textsectmap[i].baseaddr + uintptr(off) - uintptr(md.textsectmap[i].vaddr)
+ break
+ }
}
+ } else {
+ res = md.text + uintptr(off)
}
if res > md.etext {

View File

@ -1,2 +1 @@
d76dc07e475b2905b5fec1cf319b6356 golang-19087:a15f344a9efa-xattrs.tar
2cdbad6baefcf1007f3cf54a5bc878b7 go1.3.3.src.tar.gz
SHA512 (go1.11.2.src.tar.gz) = 3d9b182718c7615975a4b47cecb9ff2a8ce62156461e4112452c14617ea226121e7ab736a469050f14c89861cc4934ddd2df295b80fffff0a2dd6c155eaf0aee

97
tzdata-fix.patch Normal file
View File

@ -0,0 +1,97 @@
From 8890527476e25747f063377d637b106db0008329 Mon Sep 17 00:00:00 2001
From: Alberto Donizetti <alb.donizetti@gmail.com>
Date: Thu, 9 Mar 2017 13:20:54 +0100
Subject: [PATCH] [release-branch.go1.8] time: make the ParseInLocation test
more robust
The tzdata 2017a update (2017-02-28) changed the abbreviation of the
Asia/Baghdad time zone (used in TestParseInLocation) from 'AST' to the
numeric '+03'.
Update the test so that it skips the checks if we're using a recent
tzdata release.
Fixes #19457
Change-Id: I45d705a5520743a611bdd194dc8f8d618679980c
Reviewed-on: https://go-review.googlesource.com/37964
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
(cherry picked from commit 91563ced5897faf729a34be7081568efcfedda31)
Reviewed-on: https://go-review.googlesource.com/37991
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
---
src/time/format_test.go | 41 +++++++++++++++++++++++++++++++----------
1 file changed, 31 insertions(+), 10 deletions(-)
diff --git a/src/time/format_test.go b/src/time/format_test.go
index 219c2ca..d0013bc 100644
--- a/src/time/format_test.go
+++ b/src/time/format_test.go
@@ -245,27 +245,45 @@ func TestParseDayOutOfRange(t *testing.T) {
}
}
+// TestParseInLocation checks that the Parse and ParseInLocation
+// functions do not get confused by the fact that AST (Arabia Standard
+// Time) and AST (Atlantic Standard Time) are different time zones,
+// even though they have the same abbreviation.
+//
+// ICANN has been slowly phasing out invented abbreviation in favor of
+// numeric time zones (for example, the Asia/Baghdad time zone
+// abbreviation got changed from AST to +03 in the 2017a tzdata
+// release); but we still want to make sure that the time package does
+// not get confused on systems with slightly older tzdata packages.
func TestParseInLocation(t *testing.T) {
- // Check that Parse (and ParseInLocation) understand that
- // Feb 01 AST (Arabia Standard Time) and Feb 01 AST (Atlantic Standard Time)
- // are in different time zones even though both are called AST
baghdad, err := LoadLocation("Asia/Baghdad")
if err != nil {
t.Fatal(err)
}
- t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", baghdad)
+ var t1, t2 Time
+
+ t1, err = ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", baghdad)
if err != nil {
t.Fatal(err)
}
- t2 := Date(2013, February, 1, 00, 00, 00, 0, baghdad)
- if t1 != t2 {
- t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad) = %v, want %v", t1, t2)
- }
+
_, offset := t1.Zone()
- if offset != 3*60*60 {
- t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad).Zone = _, %d, want _, %d", offset, 3*60*60)
+
+ // A zero offset means that ParseInLocation did not recognize the
+ // 'AST' abbreviation as matching the current location (Baghdad,
+ // where we'd expect a +03 hrs offset); likely because we're using
+ // a recent tzdata release (2017a or newer).
+ // If it happens, skip the Baghdad test.
+ if offset != 0 {
+ t2 = Date(2013, February, 1, 00, 00, 00, 0, baghdad)
+ if t1 != t2 {
+ t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad) = %v, want %v", t1, t2)
+ }
+ if offset != 3*60*60 {
+ t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad).Zone = _, %d, want _, %d", offset, 3*60*60)
+ }
}
blancSablon, err := LoadLocation("America/Blanc-Sablon")
@@ -273,6 +291,9 @@ func TestParseInLocation(t *testing.T) {
t.Fatal(err)
}
+ // In this case 'AST' means 'Atlantic Standard Time', and we
+ // expect the abbreviation to correctly match the american
+ // location.
t1, err = ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", blancSablon)
if err != nil {
t.Fatal(err)