Bug 898431: Update NSS to NSS 3.15.4 beta 5 (NSS_3_15_4_BETA5), r=me
authorBrian Smith <brian@briansmith.org>
Tue, 26 Nov 2013 20:21:14 -0800
changeset 157714 c3b13e75034a494c17505ea42299edcc08a9b32e
parent 157713 9849749f362326a0c48b53712e9444c424211aa1
child 157715 3e6abaea8f5893b7af3dd466174c73f69b073fa4
push id25719
push usercbook@mozilla.com
push dateWed, 27 Nov 2013 09:57:23 +0000
treeherdermozilla-central@2e3d89ed5dc7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs898431
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 898431: Update NSS to NSS 3.15.4 beta 5 (NSS_3_15_4_BETA5), r=me
security/nss/TAG-INFO
security/nss/coreconf/coreconf.dep
security/nss/lib/freebl/unix_rand.c
security/nss/lib/ssl/ssl3gthr.c
security/nss/lib/ssl/sslsecur.c
security/patches/README
security/patches/bug-935831.patch
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_15_4_BETA4
+NSS_3_15_4_BETA5
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,9 +5,8 @@
 
 /*
  * A dummy header file that is a dependency for all the object files.
  * Used to force a full recompilation of NSS in Mozilla's Tinderbox
  * depend builds.  See comments in rules.mk.
  */
 
 #error "Do not include this header file."
-
--- a/security/nss/lib/freebl/unix_rand.c
+++ b/security/nss/lib/freebl/unix_rand.c
@@ -954,35 +954,44 @@ void RNG_SystemInfoForRNG(void)
 
 }
 
 #define TOTAL_FILE_LIMIT 1000000	/* one million */
 
 size_t RNG_FileUpdate(const char *fileName, size_t limit)
 {
     FILE *        file;
-    size_t        bytes;
+    int           fd;
+    int           bytes;
     size_t        fileBytes = 0;
     struct stat   stat_buf;
     unsigned char buffer[BUFSIZ];
     static size_t totalFileBytes = 0;
     
     /* suppress valgrind warnings due to holes in struct stat */
     memset(&stat_buf, 0, sizeof(stat_buf));
 
     if (stat((char *)fileName, &stat_buf) < 0)
 	return fileBytes;
     RNG_RandomUpdate(&stat_buf, sizeof(stat_buf));
     
     file = fopen(fileName, "r");
     if (file != NULL) {
+	/* Read from the underlying file descriptor directly to bypass stdio
+	 * buffering and avoid reading more bytes than we need from
+	 * /dev/urandom. NOTE: we can't use fread with unbuffered I/O because
+	 * fread may return EOF in unbuffered I/O mode on Android.
+	 *
+	 * Moreover, we read into a buffer of size BUFSIZ, so buffered I/O
+	 * has no performance advantage. */
+	fd = fileno(file);
 	while (limit > fileBytes) {
 	    bytes = PR_MIN(sizeof buffer, limit - fileBytes);
-	    bytes = fread(buffer, 1, bytes, file);
-	    if (bytes == 0) 
+	    bytes = read(fd, buffer, bytes);
+	    if (bytes <= 0)
 		break;
 	    RNG_RandomUpdate(buffer, bytes);
 	    fileBytes      += bytes;
 	    totalFileBytes += bytes;
 	    /* after TOTAL_FILE_LIMIT has been reached, only read in first
 	    ** buffer of data from each subsequent file.
 	    */
 	    if (totalFileBytes > TOTAL_FILE_LIMIT) 
@@ -1121,28 +1130,35 @@ static void rng_systemJitter(void)
    } else {
 	fileToRead++;
    }
 }
 
 size_t RNG_SystemRNG(void *dest, size_t maxLen)
 {
     FILE *file;
-    size_t bytes;
+    int fd;
+    int bytes;
     size_t fileBytes = 0;
     unsigned char *buffer = dest;
 
     file = fopen("/dev/urandom", "r");
     if (file == NULL) {
 	return rng_systemFromNoise(dest, maxLen);
     }
+    /* Read from the underlying file descriptor directly to bypass stdio
+     * buffering and avoid reading more bytes than we need from /dev/urandom.
+     * NOTE: we can't use fread with unbuffered I/O because fread may return
+     * EOF in unbuffered I/O mode on Android.
+     */
+    fd = fileno(file);
     while (maxLen > fileBytes) {
 	bytes = maxLen - fileBytes;
-	bytes = fread(buffer, 1, bytes, file);
-	if (bytes == 0) 
+	bytes = read(fd, buffer, bytes);
+	if (bytes <= 0)
 	    break;
 	fileBytes += bytes;
 	buffer += bytes;
     }
     fclose(file);
     if (fileBytes != maxLen) {
 	PORT_SetError(SEC_ERROR_NEED_RANDOM);  /* system RNG failed */
 	fileBytes = 0;
--- a/security/nss/lib/ssl/ssl3gthr.c
+++ b/security/nss/lib/ssl/ssl3gthr.c
@@ -320,16 +320,22 @@ ssl3_GatherCompleteHandshake(sslSocket *
 	    /* ssl3_HandleHandshake previously returned SECWouldBlock and the
 	     * as-yet-unprocessed plaintext of that previous handshake record.
 	     * We need to process it now before we overwrite it with the next
 	     * handshake record.
 	     */
 	    rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
 	} else {
 	    /* bring in the next sslv3 record. */
+	    if (ss->recvdCloseNotify) {
+		/* RFC 5246 Section 7.2.1:
+		 *   Any data received after a closure alert is ignored.
+		 */
+		return 0;
+	    }
 	    if (!IS_DTLS(ss)) {
 		rv = ssl3_GatherData(ss, &ss->gs, flags);
 	    } else {
 		rv = dtls_GatherData(ss, &ss->gs, flags);
 		
 		/* If we got a would block error, that means that no data was
 		 * available, so we check the timer to see if it's time to
 		 * retransmit */
@@ -365,30 +371,29 @@ ssl3_GatherCompleteHandshake(sslSocket *
 		    cText.seq_num.high <<= 8; cText.seq_num.low <<= 8;
 		    cText.seq_num.high |= ss->gs.hdr[3 + i];
 		    cText.seq_num.low |= ss->gs.hdr[7 + i];
 		}
 	    }
 
 	    cText.buf     = &ss->gs.inbuf;
 	    rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
-
-	    if (rv == (int) SECSuccess && ss->gs.buf.len > 0) {
-		/* We have application data to return to the application. This
-		 * prioritizes returning application data to the application over
-		 * completing any renegotiation handshake we may be doing.
-		 */
-		PORT_Assert(ss->firstHsDone);
-		PORT_Assert(cText.type == content_application_data);
-		break;
-	    }
 	}
 	if (rv < 0) {
 	    return ss->recvdCloseNotify ? 0 : rv;
 	}
+	if (ss->gs.buf.len > 0) {
+	    /* We have application data to return to the application. This
+	     * prioritizes returning application data to the application over
+	     * completing any renegotiation handshake we may be doing.
+	     */
+	    PORT_Assert(ss->firstHsDone);
+	    PORT_Assert(cText.type == content_application_data);
+	    break;
+	}
 
 	PORT_Assert(keepGoing);
 	ssl_GetSSL3HandshakeLock(ss);
 	if (ss->ssl3.hs.ws == idle_handshake) {
 	    /* We are done with the current handshake so stop trying to
 	     * handshake. Note that it would be safe to test ss->firstHsDone
 	     * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
 	     * we prioritize completing a renegotiation handshake over sending
--- a/security/nss/lib/ssl/sslsecur.c
+++ b/security/nss/lib/ssl/sslsecur.c
@@ -272,17 +272,17 @@ SSL_ReHandshake(PRFileDesc *fd, PRBool f
 
     if (!ss->opt.useSecurity)
 	return SECSuccess;
     
     ssl_Get1stHandshakeLock(ss);
 
     /* SSL v2 protocol does not support subsequent handshakes. */
     if (ss->version < SSL_LIBRARY_VERSION_3_0) {
-	PORT_SetError(SEC_ERROR_INVALID_ARGS);
+	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
 	rv = SECFailure;
     } else {
 	ssl_GetSSL3HandshakeLock(ss);
 	rv = ssl3_RedoHandshake(ss, flushCache); /* force full handshake. */
 	ssl_ReleaseSSL3HandshakeLock(ss);
     }
 
     ssl_Release1stHandshakeLock(ss);
@@ -1232,17 +1232,16 @@ ssl_SecureRead(sslSocket *ss, unsigned c
     return ssl_SecureRecv(ss, buf, len, 0);
 }
 
 /* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
 int
 ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
 {
     int rv = 0;
-    PRBool falseStart = PR_FALSE;
 
     SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
 		SSL_GETPID(), ss->fd, len));
 
     if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
 	PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
     	rv = PR_FAILURE;
 	goto done;
@@ -1267,16 +1266,17 @@ ssl_SecureSend(sslSocket *ss, const unsi
     if (rv < 0) {
 	goto done;
     }
 
     if (len > 0) 
     	ss->writerThread = PR_GetCurrentThread();
     /* If any of these is non-zero, the initial handshake is not done. */
     if (!ss->firstHsDone) {
+	PRBool falseStart = PR_FALSE;
 	ssl_Get1stHandshakeLock(ss);
 	if (ss->opt.enableFalseStart &&
 	    ss->version >= SSL_LIBRARY_VERSION_3_0) {
 	    ssl_GetSSL3HandshakeLock(ss);
 	    falseStart = ss->ssl3.hs.canFalseStart;
 	    ssl_ReleaseSSL3HandshakeLock(ss);
 	}
 	if (!falseStart &&
--- a/security/patches/README
+++ b/security/patches/README
@@ -1,4 +1,2 @@
 This directory contains patches that were added locally
 on top of the NSS release.
-
-bug-935831.patch Backout the fix for bug 927230.
deleted file mode 100644
--- a/security/patches/bug-935831.patch
+++ /dev/null
@@ -1,50 +0,0 @@
-# HG changeset patch
-# Parent cb500491e8a524edb44213d1a787adb98c385ecd
-# User Richard Newman <rnewman@mozilla.com>
-
-Back out Bug 927230 for Android 2.3 startup crash. r=briansmith
-
-diff --git a/security/nss/lib/freebl/unix_rand.c b/security/nss/lib/freebl/unix_rand.c
---- a/security/nss/lib/freebl/unix_rand.c
-+++ b/security/nss/lib/freebl/unix_rand.c
-@@ -969,20 +969,16 @@ size_t RNG_FileUpdate(const char *fileNa
-     memset(&stat_buf, 0, sizeof(stat_buf));
- 
-     if (stat((char *)fileName, &stat_buf) < 0)
- 	return fileBytes;
-     RNG_RandomUpdate(&stat_buf, sizeof(stat_buf));
-     
-     file = fopen(fileName, "r");
-     if (file != NULL) {
--	/* Set buffering mode to unbuffered I/O to avoid reading more bytes
--	 * than we need from /dev/urandom. Moreover, we read into a buffer
--	 * of size BUFSIZ, so buffered I/O has no performance advantage. */
--	setvbuf(file, NULL, _IONBF, 0);
- 	while (limit > fileBytes) {
- 	    bytes = PR_MIN(sizeof buffer, limit - fileBytes);
- 	    bytes = fread(buffer, 1, bytes, file);
- 	    if (bytes == 0) 
- 		break;
- 	    RNG_RandomUpdate(buffer, bytes);
- 	    fileBytes      += bytes;
- 	    totalFileBytes += bytes;
-@@ -1133,19 +1129,16 @@ size_t RNG_SystemRNG(void *dest, size_t 
-     size_t bytes;
-     size_t fileBytes = 0;
-     unsigned char *buffer = dest;
- 
-     file = fopen("/dev/urandom", "r");
-     if (file == NULL) {
- 	return rng_systemFromNoise(dest, maxLen);
-     }
--    /* Set buffering mode to unbuffered I/O to avoid reading more bytes
--     * than we need from /dev/urandom. */
--    setvbuf(file, NULL, _IONBF, 0);
-     while (maxLen > fileBytes) {
- 	bytes = maxLen - fileBytes;
- 	bytes = fread(buffer, 1, bytes, file);
- 	if (bytes == 0) 
- 	    break;
- 	fileBytes += bytes;
- 	buffer += bytes;
-     }