diff mbox

libgo patch committed: Update to 1.3.3

Message ID CAOyqgcUeDJh=Odkmyx7xPg4XcixhksdxMov9eeU=HtObA7_pEQ@mail.gmail.com
State New
Headers show

Commit Message

Ian Lance Taylor Oct. 27, 2014, 4:57 p.m. UTC
This patch to libgo updates it to the Go 1.3.3 release.  This is just
a few bug fixes.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r 03219f2d0191 libgo/MERGE
--- a/libgo/MERGE	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/MERGE	Mon Oct 27 09:34:59 2014 -0700
@@ -1,4 +1,4 @@ 
-9895f9e36435
+f44017549ff9
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
diff -r 03219f2d0191 libgo/go/compress/gzip/gzip.go
--- a/libgo/go/compress/gzip/gzip.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/compress/gzip/gzip.go	Mon Oct 27 09:34:59 2014 -0700
@@ -245,7 +245,8 @@ 
 	return z.err
 }
 
-// Close closes the Writer. It does not close the underlying io.Writer.
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
 func (z *Writer) Close() error {
 	if z.err != nil {
 		return z.err
diff -r 03219f2d0191 libgo/go/compress/zlib/writer.go
--- a/libgo/go/compress/zlib/writer.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/compress/zlib/writer.go	Mon Oct 27 09:34:59 2014 -0700
@@ -174,7 +174,8 @@ 
 	return z.err
 }
 
-// Calling Close does not close the wrapped io.Writer originally passed to NewWriter.
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
 func (z *Writer) Close() error {
 	if !z.wroteHeader {
 		z.err = z.writeHeader()
diff -r 03219f2d0191 libgo/go/crypto/rsa/pkcs1v15.go
--- a/libgo/go/crypto/rsa/pkcs1v15.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/rsa/pkcs1v15.go	Mon Oct 27 09:34:59 2014 -0700
@@ -53,11 +53,14 @@ 
 	if err := checkPub(&priv.PublicKey); err != nil {
 		return nil, err
 	}
-	valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
-	if err == nil && valid == 0 {
-		err = ErrDecryption
+	valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
+	if err != nil {
+		return
 	}
-
+	if valid == 0 {
+		return nil, ErrDecryption
+	}
+	out = out[index:]
 	return
 }
 
@@ -80,21 +83,32 @@ 
 	}
 	k := (priv.N.BitLen() + 7) / 8
 	if k-(len(key)+3+8) < 0 {
-		err = ErrDecryption
-		return
+		return ErrDecryption
 	}
 
-	valid, msg, err := decryptPKCS1v15(rand, priv, ciphertext)
+	valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
 	if err != nil {
 		return
 	}
 
-	valid &= subtle.ConstantTimeEq(int32(len(msg)), int32(len(key)))
-	subtle.ConstantTimeCopy(valid, key, msg)
+	if len(em) != k {
+		// This should be impossible because decryptPKCS1v15 always
+		// returns the full slice.
+		return ErrDecryption
+	}
+
+	valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
+	subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
 	return
 }
 
-func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, msg []byte, err error) {
+// decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
+// rand is not nil. It returns one or zero in valid that indicates whether the
+// plaintext was correctly structured. In either case, the plaintext is
+// returned in em so that it may be read independently of whether it was valid
+// in order to maintain constant memory access patterns. If the plaintext was
+// valid then index contains the index of the original message in em.
+func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) (valid int, em []byte, index int, err error) {
 	k := (priv.N.BitLen() + 7) / 8
 	if k < 11 {
 		err = ErrDecryption
@@ -107,7 +121,7 @@ 
 		return
 	}
 
-	em := leftPad(m.Bytes(), k)
+	em = leftPad(m.Bytes(), k)
 	firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
 	secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
 
@@ -115,8 +129,7 @@ 
 	// octets, followed by a 0, followed by the message.
 	//   lookingForIndex: 1 iff we are still looking for the zero.
 	//   index: the offset of the first zero byte.
-	var lookingForIndex, index int
-	lookingForIndex = 1
+	lookingForIndex := 1
 
 	for i := 2; i < len(em); i++ {
 		equals0 := subtle.ConstantTimeByteEq(em[i], 0)
@@ -129,8 +142,8 @@ 
 	validPS := subtle.ConstantTimeLessOrEq(2+8, index)
 
 	valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
-	msg = em[index+1:]
-	return
+	index = subtle.ConstantTimeSelect(valid, index+1, 0)
+	return valid, em, index, nil
 }
 
 // nonZeroRandomBytes fills the given slice with non-zero random octets.
diff -r 03219f2d0191 libgo/go/crypto/rsa/pkcs1v15_test.go
--- a/libgo/go/crypto/rsa/pkcs1v15_test.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/rsa/pkcs1v15_test.go	Mon Oct 27 09:34:59 2014 -0700
@@ -227,6 +227,26 @@ 
 	}
 }
 
+func TestShortSessionKey(t *testing.T) {
+	// This tests that attempting to decrypt a session key where the
+	// ciphertext is too small doesn't run outside the array bounds.
+	ciphertext, err := EncryptPKCS1v15(rand.Reader, &rsaPrivateKey.PublicKey, []byte{1})
+	if err != nil {
+		t.Fatalf("Failed to encrypt short message: %s", err)
+	}
+
+	var key [32]byte
+	if err := DecryptPKCS1v15SessionKey(nil, rsaPrivateKey, ciphertext, key[:]); err != nil {
+		t.Fatalf("Failed to decrypt short message: %s", err)
+	}
+
+	for _, v := range key {
+		if v != 0 {
+			t.Fatal("key was modified when ciphertext was invalid")
+		}
+	}
+}
+
 // In order to generate new test vectors you'll need the PEM form of this key:
 // -----BEGIN RSA PRIVATE KEY-----
 // MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
diff -r 03219f2d0191 libgo/go/crypto/subtle/constant_time.go
--- a/libgo/go/crypto/subtle/constant_time.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/subtle/constant_time.go	Mon Oct 27 09:34:59 2014 -0700
@@ -49,9 +49,14 @@ 
 	return int(z & 1)
 }
 
-// ConstantTimeCopy copies the contents of y into x iff v == 1. If v == 0, x is left unchanged.
-// Its behavior is undefined if v takes any other value.
+// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
+// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
+// takes any other value.
 func ConstantTimeCopy(v int, x, y []byte) {
+	if len(x) != len(y) {
+		panic("subtle: slices have different lengths")
+	}
+
 	xmask := byte(v - 1)
 	ymask := byte(^(v - 1))
 	for i := 0; i < len(x); i++ {
diff -r 03219f2d0191 libgo/go/crypto/tls/handshake_server.go
--- a/libgo/go/crypto/tls/handshake_server.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/tls/handshake_server.go	Mon Oct 27 09:34:59 2014 -0700
@@ -214,6 +214,10 @@ 
 func (hs *serverHandshakeState) checkForResumption() bool {
 	c := hs.c
 
+	if c.config.SessionTicketsDisabled {
+		return false
+	}
+
 	var ok bool
 	if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok {
 		return false
diff -r 03219f2d0191 libgo/go/crypto/tls/handshake_server_test.go
--- a/libgo/go/crypto/tls/handshake_server_test.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/tls/handshake_server_test.go	Mon Oct 27 09:34:59 2014 -0700
@@ -557,6 +557,32 @@ 
 	runServerTestTLS12(t, test)
 }
 
+func TestResumptionDisabled(t *testing.T) {
+	sessionFilePath := tempFile("")
+	defer os.Remove(sessionFilePath)
+
+	config := *testConfig
+
+	test := &serverTest{
+		name:    "IssueTicketPreDisable",
+		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+
+	config.SessionTicketsDisabled = true
+
+	test = &serverTest{
+		name:    "ResumeDisabled",
+		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+
+	// One needs to manually confirm that the handshake in the golden data
+	// file for ResumeDisabled does not include a resumption handshake.
+}
+
 // cert.pem and key.pem were generated with generate_cert.go
 // Thus, they have no ExtKeyUsage fields and trigger an error
 // when verification is turned on.
diff -r 03219f2d0191 libgo/go/crypto/tls/ticket.go
--- a/libgo/go/crypto/tls/ticket.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/tls/ticket.go	Mon Oct 27 09:34:59 2014 -0700
@@ -153,7 +153,8 @@ 
 }
 
 func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
-	if len(encrypted) < aes.BlockSize+sha256.Size {
+	if c.config.SessionTicketsDisabled ||
+		len(encrypted) < aes.BlockSize+sha256.Size {
 		return nil, false
 	}
 
diff -r 03219f2d0191 libgo/go/net/dnsconfig_unix.go
--- a/libgo/go/net/dnsconfig_unix.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/dnsconfig_unix.go	Mon Oct 27 09:34:59 2014 -0700
@@ -75,19 +75,19 @@ 
 			for i := 1; i < len(f); i++ {
 				s := f[i]
 				switch {
-				case len(s) >= 6 && s[0:6] == "ndots:":
+				case hasPrefix(s, "ndots:"):
 					n, _, _ := dtoi(s, 6)
 					if n < 1 {
 						n = 1
 					}
 					conf.ndots = n
-				case len(s) >= 8 && s[0:8] == "timeout:":
+				case hasPrefix(s, "timeout:"):
 					n, _, _ := dtoi(s, 8)
 					if n < 1 {
 						n = 1
 					}
 					conf.timeout = n
-				case len(s) >= 8 && s[0:9] == "attempts:":
+				case hasPrefix(s, "attempts:"):
 					n, _, _ := dtoi(s, 9)
 					if n < 1 {
 						n = 1
@@ -103,3 +103,7 @@ 
 
 	return conf, nil
 }
+
+func hasPrefix(s, prefix string) bool {
+	return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
diff -r 03219f2d0191 libgo/go/net/fd_unix.go
--- a/libgo/go/net/fd_unix.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/fd_unix.go	Mon Oct 27 09:34:59 2014 -0700
@@ -68,16 +68,19 @@ 
 	return fd.net + ":" + ls + "->" + rs
 }
 
-func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
 	// Do not need to call fd.writeLock here,
 	// because fd is not yet accessible to user,
 	// so no concurrent operations are possible.
-	if err := fd.pd.PrepareWrite(); err != nil {
-		return err
-	}
 	switch err := syscall.Connect(fd.sysfd, ra); err {
 	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
 	case nil, syscall.EISCONN:
+		if !deadline.IsZero() && deadline.Before(time.Now()) {
+			return errTimeout
+		}
+		if err := fd.init(); err != nil {
+			return err
+		}
 		return nil
 	case syscall.EINVAL:
 		// On Solaris we can see EINVAL if the socket has
@@ -92,6 +95,13 @@ 
 	default:
 		return err
 	}
+	if err := fd.init(); err != nil {
+		return err
+	}
+	if !deadline.IsZero() {
+		fd.setWriteDeadline(deadline)
+		defer fd.setWriteDeadline(noDeadline)
+	}
 	for {
 		// Performing multiple connect system calls on a
 		// non-blocking socket under Unix variants does not
diff -r 03219f2d0191 libgo/go/net/fd_windows.go
--- a/libgo/go/net/fd_windows.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/fd_windows.go	Mon Oct 27 09:34:59 2014 -0700
@@ -313,10 +313,17 @@ 
 	runtime.SetFinalizer(fd, (*netFD).Close)
 }
 
-func (fd *netFD) connect(la, ra syscall.Sockaddr) error {
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
 	// Do not need to call fd.writeLock here,
 	// because fd is not yet accessible to user,
 	// so no concurrent operations are possible.
+	if err := fd.init(); err != nil {
+		return err
+	}
+	if !deadline.IsZero() {
+		fd.setWriteDeadline(deadline)
+		defer fd.setWriteDeadline(noDeadline)
+	}
 	if !canUseConnectEx(fd.net) {
 		return syscall.Connect(fd.sysfd, ra)
 	}
diff -r 03219f2d0191 libgo/go/net/http/httptest/server_test.go
--- a/libgo/go/net/http/httptest/server_test.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/http/httptest/server_test.go	Mon Oct 27 09:34:59 2014 -0700
@@ -30,6 +30,7 @@ 
 }
 
 func TestIssue7264(t *testing.T) {
+	t.Skip("broken test - removed at tip")
 	for i := 0; i < 1000; i++ {
 		func() {
 			inHandler := make(chan bool, 1)
diff -r 03219f2d0191 libgo/go/net/sock_posix.go
--- a/libgo/go/net/sock_posix.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/sock_posix.go	Mon Oct 27 09:34:59 2014 -0700
@@ -107,24 +107,18 @@ 
 			}
 		}
 	}
-	if err := fd.init(); err != nil {
-		return err
-	}
 	var rsa syscall.Sockaddr
 	if raddr != nil {
 		if rsa, err = raddr.sockaddr(fd.family); err != nil {
 			return err
-		} else if rsa != nil {
-			if !deadline.IsZero() {
-				fd.setWriteDeadline(deadline)
-			}
-			if err := fd.connect(lsa, rsa); err != nil {
-				return err
-			}
-			fd.isConnected = true
-			if !deadline.IsZero() {
-				fd.setWriteDeadline(noDeadline)
-			}
+		}
+		if err := fd.connect(lsa, rsa, deadline); err != nil {
+			return err
+		}
+		fd.isConnected = true
+	} else {
+		if err := fd.init(); err != nil {
+			return err
 		}
 	}
 	lsa, _ = syscall.Getsockname(fd.sysfd)
diff -r 03219f2d0191 libgo/go/net/testdata/resolv.conf
--- a/libgo/go/net/testdata/resolv.conf	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/net/testdata/resolv.conf	Mon Oct 27 09:34:59 2014 -0700
@@ -3,3 +3,4 @@ 
 domain Home
 nameserver 192.168.1.1
 options ndots:5 timeout:10 attempts:3 rotate
+options attempts 3
diff -r 03219f2d0191 libgo/go/time/format_test.go
--- a/libgo/go/time/format_test.go	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/time/format_test.go	Mon Oct 27 09:34:59 2014 -0700
@@ -183,39 +183,45 @@ 
 	}
 }
 
-func TestParseInSydney(t *testing.T) {
-	loc, err := LoadLocation("Australia/Sydney")
+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)
 	}
 
-	// Check that Parse (and ParseInLocation) understand
-	// that Feb EST and Aug EST are different time zones in Sydney
-	// even though both are called EST.
-	t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 EST", loc)
+	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, loc)
+	t2 := Date(2013, February, 1, 00, 00, 00, 0, baghdad)
 	if t1 != t2 {
-		t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney) = %v, want %v", t1, t2)
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad) = %v, want %v", t1, t2)
 	}
 	_, offset := t1.Zone()
-	if offset != 11*60*60 {
-		t.Fatalf("ParseInLocation(Feb 01 2013 EST, Sydney).Zone = _, %d, want _, %d", offset, 11*60*60)
+	if offset != 3*60*60 {
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad).Zone = _, %d, want _, %d", offset, 3*60*60)
 	}
 
-	t1, err = ParseInLocation("Jan 02 2006 MST", "Aug 01 2013 EST", loc)
+	blancSablon, err := LoadLocation("America/Blanc-Sablon")
 	if err != nil {
 		t.Fatal(err)
 	}
-	t2 = Date(2013, August, 1, 00, 00, 00, 0, loc)
+
+	t1, err = ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", blancSablon)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t2 = Date(2013, February, 1, 00, 00, 00, 0, blancSablon)
 	if t1 != t2 {
-		t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney) = %v, want %v", t1, t2)
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon) = %v, want %v", t1, t2)
 	}
 	_, offset = t1.Zone()
-	if offset != 10*60*60 {
-		t.Fatalf("ParseInLocation(Aug 01 2013 EST, Sydney).Zone = _, %d, want _, %d", offset, 10*60*60)
+	if offset != -4*60*60 {
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon).Zone = _, %d, want _, %d", offset, -4*60*60)
 	}
 }
 
diff -r 03219f2d0191 libgo/runtime/runtime.c
--- a/libgo/runtime/runtime.c	Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/runtime/runtime.c	Mon Oct 27 09:34:59 2014 -0700
@@ -112,8 +112,6 @@ 
 	syscall_Envs.__values = (void*)s;
 	syscall_Envs.__count = n;
 	syscall_Envs.__capacity = n;
-
-	traceback_cache = ~(uint32)0;
 }
 
 int32
@@ -309,6 +307,16 @@ 
 {
 	const byte *p;
 	intgo i, n;
+	bool tmp;
+	
+	// gotraceback caches the GOTRACEBACK setting in traceback_cache.
+	// gotraceback can be called before the environment is available.
+	// traceback_cache must be reset after the environment is made
+	// available, in order for the environment variable to take effect.
+	// The code is fixed differently in Go 1.4.
+	// This is a limited fix for Go 1.3.3.
+	traceback_cache = ~(uint32)0;
+	runtime_gotraceback(&tmp);
 
 	p = runtime_getenv("GODEBUG");
 	if(p == nil)