[Pkg-golang-commits] [golang] 02/03: New upstream version 1.7.4
Tianon Gravi
tianon at debian.org
Fri Dec 2 00:10:18 UTC 2016
This is an automated email from the git hooks/post-receive script.
tianon pushed a commit to branch golang-1.7
in repository golang.
commit de85607dbaa69b32855648c1f11616b69746cf88
Author: Tianon Gravi <tianon at debian.org>
Date: Thu Dec 1 16:09:07 2016 -0800
New upstream version 1.7.4
---
VERSION | 2 +-
doc/devel/release.html | 15 ++++-
doc/go1.7.html | 3 +-
doc/install-source.html | 41 ++++++++-----
src/crypto/x509/cert_pool.go | 15 +++++
src/crypto/x509/root_cgo_darwin.go | 81 ++++++++++++++++++++++---
src/crypto/x509/root_darwin.go | 114 +++++++++++++++++++++++++++++++++++-
src/crypto/x509/root_darwin_test.go | 1 +
src/mime/multipart/formdata.go | 4 +-
9 files changed, 246 insertions(+), 30 deletions(-)
diff --git a/VERSION b/VERSION
index 816aead..83caa74 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.7.3
\ No newline at end of file
+go1.7.4
\ No newline at end of file
diff --git a/doc/devel/release.html b/doc/devel/release.html
index 9a4daf1..51957df 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -63,6 +63,12 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.3">Go
1.7.3 milestone</a> on our issue tracker for details.
</p>
+<p>
+go1.7.4 (released 2016/12/01) includes two security fixes.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.4">Go
+1.7.4 milestone</a> on our issue tracker for details.
+</p>
+
<h2 id="go1.6">go1.6 (released 2016/02/17)</h2>
<p>
@@ -89,11 +95,18 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.6.2">Go
<p>
go1.6.3 (released 2016/07/17) includes security fixes to the
<code>net/http/cgi</code> package and <code>net/http</code> package when used in
-a CGI environment. This release also adds support for macOS Sierra.
+a CGI environment.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.6.3">Go
1.6.3 milestone</a> on our issue tracker for details.
</p>
+<p>
+go1.6.4 (released 2016/12/01) includes two security fixes.
+It contains the same fixes as Go 1.7.4 and was released at the same time.
+See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.7.4">Go
+1.7.4 milestone</a> on our issue tracker for details.
+</p>
+
<h2 id="go1.5">go1.5 (released 2015/08/19)</h2>
<p>
diff --git a/doc/go1.7.html b/doc/go1.7.html
index 762c1ec..6839c5e 100644
--- a/doc/go1.7.html
+++ b/doc/go1.7.html
@@ -67,8 +67,7 @@ This change has no effect on the correctness of existing programs.
<p>
Go 1.7 adds support for macOS 10.12 Sierra.
-This support was backported to Go 1.6.3.
-Binaries built with versions of Go before 1.6.3 will not work
+Binaries built with versions of Go before 1.7 will not work
correctly on Sierra.
</p>
diff --git a/doc/install-source.html b/doc/install-source.html
index d0a4ed2..77616c1 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -119,27 +119,39 @@ Go does not support CentOS 6 on these systems.
<p>
The Go tool chain is written in Go. To build it, you need a Go compiler installed.
The scripts that do the initial build of the tools look for an existing Go tool
-chain in <code>$HOME/go1.4</code>.
-(This path may be overridden by setting the <code>GOROOT_BOOTSTRAP</code>
-environment variable.)
+chain in <code>$GOROOT_BOOTSTRAP</code>.
+If unset, the default value of <code>GOROOT_BOOTSTRAP</code>
+is <code>$HOME/go1.4</code>.
</p>
<p>
-Build the tools with Go version 1.4 or a point release (1.4.1, 1.4.2 etc.).
-Go 1.4 binaries can be found at <a href="/dl/">the downloads page</a>.
+There are many options for the bootstrap tool chain.
+After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the
+directory containing the unpacked tree.
+For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be
+the <code>go</code> command binary for the bootstrap tool chain.
</p>
<p>
-Download the zip or tarball of Go 1.4 for your platform and extract it to
-<code>$HOME/go1.4</code> (or your nominated <code>GOROOT_BOOTSTRAP</code>
-location).
+To use a binary release as a bootstrap tool chain, see
+<a href="/dl/">the downloads page</a> or use any other
+packaged Go distribution.
</p>
<p>
-If you want to install Go 1.5 on a system that is not supported by Go 1.4 (such
-as <code>linux/ppc64</code> and <code>linux/mips64le</code>) you can either use
-<a href="/src/bootstrap.bash">bootstrap.bash</a> on a system that can bootstrap Go
-1.5 normally, or bootstrap with gccgo 5.
+To build a bootstrap tool chain from source, use
+either the git branch <code>release-branch.go1.4</code> or
+<a href="https://storage.googleapis.com/golang/go1.4-bootstrap-20161024.tar.gz">go1.4-bootstrap-20161024.tar.gz</a>,
+which contains the Go 1.4 source code plus accumulated fixes
+to keep the tools running on newer operating systems.
+(Go 1.4 was the last distribution in which the tool chain was written in C.)
+</p>
+
+<p>
+To cross-compile a bootstrap tool chain from source, which is
+necessary on systems Go 1.4 did not target (for
+example, <code>linux/ppc64le</code>), install Go on a different system
+and run <a href="/src/bootstrap.bash">bootstrap.bash</a>.
</p>
<p>
@@ -158,8 +170,9 @@ and used as <code>GOROOT_BOOTSTRAP</code> to bootstrap a local build.
</p>
<p>
-To use gccgo, you need to arrange for <code>$GOROOT_BOOTSTRAP/bin/go</code> to be
-the go tool that comes as part of gccgo 5. For example on Ubuntu Vivid:
+To use gccgo as the bootstrap toolchain, you need to arrange
+for <code>$GOROOT_BOOTSTRAP/bin/go</code> to be the go tool that comes
+as part of gccgo 5. For example on Ubuntu Vivid:
</p>
<pre>
diff --git a/src/crypto/x509/cert_pool.go b/src/crypto/x509/cert_pool.go
index 59ab887..8438bf6 100644
--- a/src/crypto/x509/cert_pool.go
+++ b/src/crypto/x509/cert_pool.go
@@ -64,6 +64,21 @@ func (s *CertPool) findVerifiedParents(cert *Certificate) (parents []int, errCer
return
}
+func (s *CertPool) contains(cert *Certificate) bool {
+ if s == nil {
+ return false
+ }
+
+ candidates := s.byName[string(cert.RawSubject)]
+ for _, c := range candidates {
+ if s.certs[c].Equal(cert) {
+ return true
+ }
+ }
+
+ return false
+}
+
// AddCert adds a certificate to a pool.
func (s *CertPool) AddCert(cert *Certificate) {
if cert == nil {
diff --git a/src/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go
index a4b33c7..d599174 100644
--- a/src/crypto/x509/root_cgo_darwin.go
+++ b/src/crypto/x509/root_cgo_darwin.go
@@ -73,10 +73,11 @@ int useOldCode() {
//
// On success it returns 0 and fills pemRoots with a CFDataRef that contains the extracted root
// certificates of the system. On failure, the function returns -1.
+// Additionally, it fills untrustedPemRoots with certs that must be removed from pemRoots.
//
-// Note: The CFDataRef returned in pemRoots must be released (using CFRelease) after
-// we've consumed its content.
-int FetchPEMRoots(CFDataRef *pemRoots) {
+// Note: The CFDataRef returned in pemRoots and untrustedPemRoots must
+// be released (using CFRelease) after we've consumed its content.
+int FetchPEMRoots(CFDataRef *pemRoots, CFDataRef *untrustedPemRoots) {
if (useOldCode()) {
return FetchPEMRoots_MountainLion(pemRoots);
}
@@ -93,23 +94,69 @@ int FetchPEMRoots(CFDataRef *pemRoots) {
return -1;
}
+ // kSecTrustSettingsResult is defined as CFSTR("kSecTrustSettingsResult"),
+ // but the Go linker's internal linking mode can't handle CFSTR relocations.
+ // Create our own dynamic string instead and release it below.
+ CFStringRef policy = CFStringCreateWithCString(NULL, "kSecTrustSettingsResult", kCFStringEncodingUTF8);
+
CFMutableDataRef combinedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
+ CFMutableDataRef combinedUntrustedData = CFDataCreateMutable(kCFAllocatorDefault, 0);
for (int i = 0; i < numDomains; i++) {
CFArrayRef certs = NULL;
- // Only get certificates from domain that are trusted
OSStatus err = SecTrustSettingsCopyCertificates(domains[i], &certs);
if (err != noErr) {
continue;
}
- int numCerts = CFArrayGetCount(certs);
+ CFIndex numCerts = CFArrayGetCount(certs);
for (int j = 0; j < numCerts; j++) {
CFDataRef data = NULL;
CFErrorRef errRef = NULL;
+ CFArrayRef trustSettings = NULL;
SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex(certs, j);
if (cert == NULL) {
continue;
}
+ // We only want trusted certs.
+ int untrusted = 0;
+ if (i != 0) {
+ // Certs found in the system domain are always trusted. If the user
+ // configures "Never Trust" on such a cert, it will also be found in the
+ // admin or user domain, causing it to be added to untrustedPemRoots. The
+ // Go code will then clean this up.
+
+ // Trust may be stored in any of the domains. According to Apple's
+ // SecTrustServer.c, "user trust settings overrule admin trust settings",
+ // so take the last trust settings array we find.
+ // Skip the system domain since it is always trusted.
+ for (int k = 1; k < numDomains; k++) {
+ CFArrayRef domainTrustSettings = NULL;
+ err = SecTrustSettingsCopyTrustSettings(cert, domains[k], &domainTrustSettings);
+ if (err == errSecSuccess && domainTrustSettings != NULL) {
+ if (trustSettings) {
+ CFRelease(trustSettings);
+ }
+ trustSettings = domainTrustSettings;
+ }
+ }
+ if (trustSettings == NULL) {
+ // "this certificate must be verified to a known trusted certificate"; aka not a root.
+ continue;
+ }
+ for (CFIndex k = 0; k < CFArrayGetCount(trustSettings); k++) {
+ CFNumberRef cfNum;
+ CFDictionaryRef tSetting = (CFDictionaryRef)CFArrayGetValueAtIndex(trustSettings, k);
+ if (CFDictionaryGetValueIfPresent(tSetting, policy, (const void**)&cfNum)){
+ SInt32 result = 0;
+ CFNumberGetValue(cfNum, kCFNumberSInt32Type, &result);
+ // TODO: The rest of the dictionary specifies conditions for evaluation.
+ if (result == kSecTrustSettingsResultDeny) {
+ untrusted = 1;
+ }
+ }
+ }
+ CFRelease(trustSettings);
+ }
// We only want to add Root CAs, so make sure Subject and Issuer Name match
CFDataRef subjectName = SecCertificateCopyNormalizedSubjectContent(cert, &errRef);
if (errRef != NULL) {
@@ -138,13 +185,16 @@ int FetchPEMRoots(CFDataRef *pemRoots) {
}
if (data != NULL) {
- CFDataAppendBytes(combinedData, CFDataGetBytePtr(data), CFDataGetLength(data));
+ CFMutableDataRef appendTo = untrusted ? combinedUntrustedData : combinedData;
+ CFDataAppendBytes(appendTo, CFDataGetBytePtr(data), CFDataGetLength(data));
CFRelease(data);
}
}
CFRelease(certs);
}
+ CFRelease(policy);
*pemRoots = combinedData;
+ *untrustedPemRoots = combinedUntrustedData;
return 0;
}
*/
@@ -158,7 +208,8 @@ func loadSystemRoots() (*CertPool, error) {
roots := NewCertPool()
var data C.CFDataRef = nil
- err := C.FetchPEMRoots(&data)
+ var untrustedData C.CFDataRef = nil
+ err := C.FetchPEMRoots(&data, &untrustedData)
if err == -1 {
// TODO: better error message
return nil, errors.New("crypto/x509: failed to load darwin system roots with cgo")
@@ -167,5 +218,19 @@ func loadSystemRoots() (*CertPool, error) {
defer C.CFRelease(C.CFTypeRef(data))
buf := C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(data)), C.int(C.CFDataGetLength(data)))
roots.AppendCertsFromPEM(buf)
- return roots, nil
+ if untrustedData == nil {
+ return roots, nil
+ }
+ defer C.CFRelease(C.CFTypeRef(untrustedData))
+ buf = C.GoBytes(unsafe.Pointer(C.CFDataGetBytePtr(untrustedData)), C.int(C.CFDataGetLength(untrustedData)))
+ untrustedRoots := NewCertPool()
+ untrustedRoots.AppendCertsFromPEM(buf)
+
+ trustedRoots := NewCertPool()
+ for _, c := range roots.certs {
+ if !untrustedRoots.contains(c) {
+ trustedRoots.AddCert(c)
+ }
+ }
+ return trustedRoots, nil
}
diff --git a/src/crypto/x509/root_darwin.go b/src/crypto/x509/root_darwin.go
index 78de56c..59b303d 100644
--- a/src/crypto/x509/root_darwin.go
+++ b/src/crypto/x509/root_darwin.go
@@ -6,12 +6,27 @@
package x509
-import "os/exec"
+import (
+ "bytes"
+ "encoding/pem"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "strconv"
+ "sync"
+ "syscall"
+)
func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
return nil, nil
}
+// This code is only used when compiling without cgo.
+// It is here, instead of root_nocgo_darwin.go, so that tests can check it
+// even if the tests are run with cgo enabled.
+// The linker will not include these unused functions in binaries built with cgo enabled.
+
func execSecurityRoots() (*CertPool, error) {
cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain")
data, err := cmd.Output()
@@ -19,7 +34,100 @@ func execSecurityRoots() (*CertPool, error) {
return nil, err
}
- roots := NewCertPool()
- roots.AppendCertsFromPEM(data)
+ var (
+ mu sync.Mutex
+ roots = NewCertPool()
+ )
+ add := func(cert *Certificate) {
+ mu.Lock()
+ defer mu.Unlock()
+ roots.AddCert(cert)
+ }
+ blockCh := make(chan *pem.Block)
+ var wg sync.WaitGroup
+ for i := 0; i < 4; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ for block := range blockCh {
+ verifyCertWithSystem(block, add)
+ }
+ }()
+ }
+ for len(data) > 0 {
+ var block *pem.Block
+ block, data = pem.Decode(data)
+ if block == nil {
+ break
+ }
+ if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
+ continue
+ }
+ blockCh <- block
+ }
+ close(blockCh)
+ wg.Wait()
return roots, nil
}
+
+func verifyCertWithSystem(block *pem.Block, add func(*Certificate)) {
+ data := pem.EncodeToMemory(block)
+ var cmd *exec.Cmd
+ if needsTmpFiles() {
+ f, err := ioutil.TempFile("", "cert")
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "can't create temporary file for cert: %v", err)
+ return
+ }
+ defer os.Remove(f.Name())
+ if _, err := f.Write(data); err != nil {
+ fmt.Fprintf(os.Stderr, "can't write temporary file for cert: %v", err)
+ return
+ }
+ if err := f.Close(); err != nil {
+ fmt.Fprintf(os.Stderr, "can't write temporary file for cert: %v", err)
+ return
+ }
+ cmd = exec.Command("/usr/bin/security", "verify-cert", "-c", f.Name(), "-l")
+ } else {
+ cmd = exec.Command("/usr/bin/security", "verify-cert", "-c", "/dev/stdin", "-l")
+ cmd.Stdin = bytes.NewReader(data)
+ }
+ if cmd.Run() == nil {
+ // Non-zero exit means untrusted
+ cert, err := ParseCertificate(block.Bytes)
+ if err != nil {
+ return
+ }
+
+ add(cert)
+ }
+}
+
+var versionCache struct {
+ sync.Once
+ major int
+}
+
+// needsTmpFiles reports whether the OS is <= 10.11 (which requires real
+// files as arguments to the security command).
+func needsTmpFiles() bool {
+ versionCache.Do(func() {
+ release, err := syscall.Sysctl("kern.osrelease")
+ if err != nil {
+ return
+ }
+ for i, c := range release {
+ if c == '.' {
+ release = release[:i]
+ break
+ }
+ }
+ major, err := strconv.Atoi(release)
+ if err != nil {
+ return
+ }
+ versionCache.major = major
+ })
+ return versionCache.major <= 15
+}
diff --git a/src/crypto/x509/root_darwin_test.go b/src/crypto/x509/root_darwin_test.go
index 8b6b151..c8ca3ea 100644
--- a/src/crypto/x509/root_darwin_test.go
+++ b/src/crypto/x509/root_darwin_test.go
@@ -29,6 +29,7 @@ func TestSystemRoots(t *testing.T) {
// On Mavericks, there are 212 bundled certs; require only
// 150 here, since this is just a sanity check, and the
// exact number will vary over time.
+ t.Logf("got %d roots", len(tt.certs))
if want, have := 150, len(tt.certs); have < want {
t.Fatalf("want at least %d system roots, have %d", want, have)
}
diff --git a/src/mime/multipart/formdata.go b/src/mime/multipart/formdata.go
index 8085bd3..c9e3188 100644
--- a/src/mime/multipart/formdata.go
+++ b/src/mime/multipart/formdata.go
@@ -79,8 +79,10 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
if err != nil {
return nil, err
}
- defer file.Close()
_, err = io.Copy(file, io.MultiReader(&b, p))
+ if cerr := file.Close(); err == nil {
+ err = cerr
+ }
if err != nil {
os.Remove(file.Name())
return nil, err
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-golang/golang.git
More information about the pkg-golang-commits
mailing list