Bug 1460617 - land NSS 8232a58332dd UPGRADE_NSS_RELEASE, r=me
authorFranziskus Kiefer <franziskuskiefer@gmail.com>
Fri, 01 Jun 2018 09:44:01 +0200
changeset 420853 4f9eec636127
parent 420852 ee1e13b50338
child 420854 ff4fa69beec8
push id103899
push userfranziskuskiefer@gmail.com
push dateFri, 01 Jun 2018 12:47:36 +0000
treeherdermozilla-inbound@4f9eec636127 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1460617
milestone62.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 1460617 - land NSS 8232a58332dd UPGRADE_NSS_RELEASE, r=me
security/nss/TAG-INFO
security/nss/automation/abi-check/expected-report-libnssutil3.so.txt
security/nss/cmd/tstclnt/tstclnt.c
security/nss/coreconf/coreconf.dep
security/nss/cpputil/scoped_ptrs.h
security/nss/gtests/ssl_gtest/tls_agent.cc
security/nss/lib/dev/devslot.c
security/nss/lib/ssl/ssl3con.c
security/nss/lib/util/nssutil.def
security/nss/lib/util/secitem.c
security/nss/lib/util/secitem.h
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-3d3e34bb7517
+8232a58332dd
--- a/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt
+++ b/security/nss/automation/abi-check/expected-report-libnssutil3.so.txt
@@ -0,0 +1,4 @@
+
+1 Added function:
+
+  'function SECStatus SECITEM_MakeItem(PLArenaPool*, SECItem*, unsigned char*, unsigned int)'    {SECITEM_MakeItem@@NSSUTIL_3.38}
--- a/security/nss/cmd/tstclnt/tstclnt.c
+++ b/security/nss/cmd/tstclnt/tstclnt.c
@@ -1152,17 +1152,17 @@ run()
 {
     int headerSeparatorPtrnId = 0;
     int error = 0;
     SECStatus rv;
     PRStatus status;
     PRInt32 filesReady;
     PRFileDesc *s = NULL;
     PRFileDesc *std_out;
-    PRPollDesc pollset[2];
+    PRPollDesc pollset[2] = { { 0 }, { 0 } };
     PRBool wrStarted = PR_FALSE;
 
     handshakeComplete = PR_FALSE;
 
     /* Create socket */
     if (useDTLS) {
         s = PR_OpenUDPSocket(addr.raw.family);
     } else {
@@ -1578,17 +1578,17 @@ run()
         }
         milliPause(50 * multiplier);
     }
 
 done:
     if (s) {
         PR_Close(s);
     }
-    if (requestFile) {
+    if (requestFile && pollset[STDIN_FD].fd) {
         PR_Close(pollset[STDIN_FD].fd);
     }
     return error;
 }
 
 int
 main(int argc, char **argv)
 {
--- a/security/nss/coreconf/coreconf.dep
+++ b/security/nss/coreconf/coreconf.dep
@@ -5,8 +5,9 @@
 
 /*
  * 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/cpputil/scoped_ptrs.h
+++ b/security/nss/cpputil/scoped_ptrs.h
@@ -40,16 +40,17 @@ struct ScopedDelete {
   void operator()(PK11Context* context) { PK11_DestroyContext(context, true); }
   void operator()(PK11GenericObject* obj) { PK11_DestroyGenericObject(obj); }
   void operator()(SSLResumptionTokenInfo* token) {
     SSL_DestroyResumptionTokenInfo(token);
   }
   void operator()(SEC_PKCS12DecoderContext* dcx) {
     SEC_PKCS12DecoderFinish(dcx);
   }
+  void operator()(CERTDistNames* names) { CERT_FreeDistNames(names); }
 };
 
 template <class T>
 struct ScopedMaybeDelete {
   void operator()(T* ptr) {
     if (ptr) {
       ScopedDelete del;
       del(ptr);
@@ -73,12 +74,13 @@ SCOPED(SECKEYPublicKey);
 SCOPED(SECKEYPrivateKey);
 SCOPED(SECKEYPrivateKeyList);
 SCOPED(PK11URI);
 SCOPED(PLArenaPool);
 SCOPED(PK11Context);
 SCOPED(PK11GenericObject);
 SCOPED(SSLResumptionTokenInfo);
 SCOPED(SEC_PKCS12DecoderContext);
+SCOPED(CERTDistNames);
 
 #undef SCOPED
 
 #endif  // scoped_ptrs_h__
--- a/security/nss/gtests/ssl_gtest/tls_agent.cc
+++ b/security/nss/gtests/ssl_gtest/tls_agent.cc
@@ -180,27 +180,27 @@ bool TlsAgent::EnsureTlsSetup(PRFileDesc
 
   SECStatus rv;
   if (!skip_version_checks_) {
     rv = SSL_VersionRangeSet(ssl_fd(), &vrange_);
     EXPECT_EQ(SECSuccess, rv);
     if (rv != SECSuccess) return false;
   }
 
+  ScopedCERTCertList anchors(CERT_NewCertList());
+  rv = SSL_SetTrustAnchors(ssl_fd(), anchors.get());
+  if (rv != SECSuccess) return false;
+
   if (role_ == SERVER) {
     EXPECT_TRUE(ConfigServerCert(name_, true));
 
     rv = SSL_SNISocketConfigHook(ssl_fd(), SniHook, this);
     EXPECT_EQ(SECSuccess, rv);
     if (rv != SECSuccess) return false;
 
-    ScopedCERTCertList anchors(CERT_NewCertList());
-    rv = SSL_SetTrustAnchors(ssl_fd(), anchors.get());
-    if (rv != SECSuccess) return false;
-
     rv = SSL_SetMaxEarlyDataSize(ssl_fd(), 1024);
     EXPECT_EQ(SECSuccess, rv);
     if (rv != SECSuccess) return false;
   } else {
     rv = SSL_SetURL(ssl_fd(), "server");
     EXPECT_EQ(SECSuccess, rv);
     if (rv != SECSuccess) return false;
   }
@@ -251,24 +251,38 @@ void TlsAgent::SetupClientAuth() {
   EXPECT_TRUE(EnsureTlsSetup());
   ASSERT_EQ(CLIENT, role_);
 
   EXPECT_EQ(SECSuccess,
             SSL_GetClientAuthDataHook(ssl_fd(), GetClientAuthDataHook,
                                       reinterpret_cast<void*>(this)));
 }
 
+void CheckCertReqAgainstDefaultCAs(const CERTDistNames* caNames) {
+  ScopedCERTDistNames expected(CERT_GetSSLCACerts(nullptr));
+
+  ASSERT_EQ(expected->nnames, caNames->nnames);
+
+  for (size_t i = 0; i < static_cast<size_t>(expected->nnames); ++i) {
+    EXPECT_EQ(SECEqual,
+              SECITEM_CompareItem(&(expected->names[i]), &(caNames->names[i])));
+  }
+}
+
 SECStatus TlsAgent::GetClientAuthDataHook(void* self, PRFileDesc* fd,
                                           CERTDistNames* caNames,
                                           CERTCertificate** clientCert,
                                           SECKEYPrivateKey** clientKey) {
   TlsAgent* agent = reinterpret_cast<TlsAgent*>(self);
   ScopedCERTCertificate peerCert(SSL_PeerCertificate(agent->ssl_fd()));
   EXPECT_TRUE(peerCert) << "Client should be able to see the server cert";
 
+  // See bug 1457716
+  // CheckCertReqAgainstDefaultCAs(caNames);
+
   ScopedCERTCertificate cert;
   ScopedSECKEYPrivateKey priv;
   if (!TlsAgent::LoadCertificate(agent->name(), &cert, &priv)) {
     return SECFailure;
   }
 
   *clientCert = cert.release();
   *clientKey = priv.release();
--- a/security/nss/lib/dev/devslot.c
+++ b/security/nss/lib/dev/devslot.c
@@ -148,17 +148,17 @@ nssSlot_IsTokenPresent(
     epv = slot->epv;
     if (!epv) {
         return PR_FALSE;
     }
 
     /* set up condition so only one thread is active in this part of the code at a time */
     PZ_Lock(slot->isPresentLock);
     while (slot->isPresentThread) {
-        PR_WaitCondVar(slot->isPresentCondition, 0);
+        PR_WaitCondVar(slot->isPresentCondition, PR_INTERVAL_NO_TIMEOUT);
     }
     /* if we were one of multiple threads here, the first thread will have
      * given us the answer, no need to make more queries of the token. */
     if (token_status_checked(slot)) {
         CK_FLAGS ckFlags = slot->ckFlags;
         PZ_Unlock(slot->isPresentLock);
         return ((ckFlags & CKF_TOKEN_PRESENT) != 0);
     }
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -6943,18 +6943,20 @@ ssl3_ParseCertificateRequestCAs(sslSocke
 
         rv = ssl3_ConsumeHandshakeNumber(ss, &len, 2, b, length);
         if (rv != SECSuccess)
             return SECFailure; /* malformed, alert has been sent */
         if (len == 0 || remaining < len + 2)
             goto alert_loser; /* malformed */
 
         remaining -= 2;
+        if (SECITEM_MakeItem(ca_list->arena, &node->name, *b, len) != SECSuccess) {
+            goto no_mem;
+        }
         node->name.len = len;
-        node->name.data = *b;
         *b += len;
         *length -= len;
         remaining -= len;
         nnames++;
         if (remaining <= 0)
             break; /* success */
 
         node->next = PORT_ArenaZNew(ca_list->arena, dnameNode);
@@ -6972,17 +6974,16 @@ ssl3_ParseCertificateRequestCAs(sslSocke
          i < nnames;
          i++, node = node->next) {
         ca_list->names[i] = node->name;
     }
 
     return SECSuccess;
 
 no_mem:
-    PORT_SetError(SEC_ERROR_NO_MEMORY);
     return SECFailure;
 
 alert_loser:
     (void)SSL3_SendAlert(ss, alert_fatal,
                          ss->version < SSL_LIBRARY_VERSION_TLS_1_0 ? illegal_parameter
                                                                    : decode_error);
     PORT_SetError(SSL_ERROR_RX_MALFORMED_CERT_REQUEST);
     return SECFailure;
@@ -11395,16 +11396,20 @@ ssl3_HandleHandshakeMessage(sslSocket *s
         PORT_SetError(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE);
         return SECFailure;
     }
 
     if (IS_DTLS(ss) && (rv != SECFailure)) {
         /* Increment the expected sequence number */
         ss->ssl3.hs.recvMessageSeq++;
     }
+
+    /* Taint the message so that it's easier to detect UAFs. */
+    PORT_Memset(b, 'N', length);
+
     return rv;
 }
 
 static SECStatus
 ssl3_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b,
                                      PRUint32 length)
 {
     SECStatus rv;
--- a/security/nss/lib/util/nssutil.def
+++ b/security/nss/lib/util/nssutil.def
@@ -317,9 +317,14 @@ NSS_SecureMemcmpZero;
 ;+};
 ;-NSSUTIL_3.35 {         # NSS Utilities 3.35 release
 ;-    global:
 ;-# private exports for softoken
 _NSSUTIL_UTF8ToWide;-
 _NSSUTIL_Access;-
 ;-    local:
 ;-       *;
-;-};
+;+NSSUTIL_3.38 {         # NSS Utilities 3.38 release
+;+    global:
+SECITEM_MakeItem;
+;+    local:
+;+       *;
+;+};
--- a/security/nss/lib/util/secitem.c
+++ b/security/nss/lib/util/secitem.c
@@ -71,16 +71,25 @@ loser:
          * If item is not NULL, the above has set item->data and
          * item->len to 0.
          */
     }
     return (NULL);
 }
 
 SECStatus
+SECITEM_MakeItem(PLArenaPool *arena, SECItem *dest, unsigned char *data,
+                 unsigned int len)
+{
+    SECItem it = { siBuffer, data, len };
+
+    return SECITEM_CopyItem(arena, dest, &it);
+}
+
+SECStatus
 SECITEM_ReallocItem(PLArenaPool *arena, SECItem *item, unsigned int oldlen,
                     unsigned int newlen)
 {
     PORT_Assert(item != NULL);
     if (item == NULL) {
         /* XXX Set error.  But to what? */
         return SECFailure;
     }
--- a/security/nss/lib/util/secitem.h
+++ b/security/nss/lib/util/secitem.h
@@ -30,16 +30,24 @@ SEC_BEGIN_PROTOS
 ** The resulting item is returned; NULL if any error occurs.
 **
 ** XXX This probably should take a SECItemType, but since that is mostly
 ** unused and our improved APIs (aka Stan) are looming, I left it out.
 */
 extern SECItem *SECITEM_AllocItem(PLArenaPool *arena, SECItem *item,
                                   unsigned int len);
 
+/* Allocate and make an item with the requested contents.
+ *
+ * We seem to have mostly given up on SECItemType, so the result is
+ * always siBuffer.
+ */
+extern SECStatus SECITEM_MakeItem(PLArenaPool *arena, SECItem *dest,
+                                  unsigned char *data, unsigned int len);
+
 /*
 ** This is a legacy function containing bugs. It doesn't update item->len,
 ** and it has other issues as described in bug 298649 and bug 298938.
 ** However, the function is  kept unchanged for consumers that might depend
 ** on the broken behaviour. New code should call SECITEM_ReallocItemV2.
 **
 ** Reallocate the data for the specified "item".  If "arena" is not NULL,
 ** then reallocate from there, otherwise reallocate from the heap.