Bug 1287711 - Make writes to SSLKEYLOGFILE thread-safe, r=mt
authorMartin Thomson <martin.thomson@gmail.com>
Tue, 03 Oct 2017 14:55:02 -0700
changeset 13622 c1866d7d7f15b3ea9de3659fbd2fdaaf4f2ae273
parent 13621 965b5533bf61ecf85e71203fa26ab33e60bb7125
child 13623 6fb9c5396d52e007c1cdc7330e062589478fdb5e
push id2402
push usermartin.thomson@gmail.com
push dateTue, 03 Oct 2017 22:23:34 +0000
reviewersmt
bugs1287711
Bug 1287711 - Make writes to SSLKEYLOGFILE thread-safe, r=mt Protect writes to the keylog file with a lock. Differential Revision: https://phabricator.services.mozilla.com/D86
lib/ssl/ssl3con.c
lib/ssl/sslimpl.h
lib/ssl/sslsock.c
--- a/lib/ssl/ssl3con.c
+++ b/lib/ssl/ssl3con.c
@@ -11191,19 +11191,20 @@ ssl3_RecordKeyLog(sslSocket *ss, const c
     offset += SSL3_RANDOM_LENGTH * 2;
     buf[offset++] = ' ';
     hexEncode(buf + offset, keyData->data, keyData->len);
     offset += keyData->len * 2;
     buf[offset++] = '\n';
 
     PORT_Assert(offset == len);
 
-    if (fwrite(buf, len, 1, ssl_keylog_iob) != 1)
-        return;
-    fflush(ssl_keylog_iob);
+    PZ_Lock(ssl_keylog_lock);
+    if (fwrite(buf, len, 1, ssl_keylog_iob) == 1)
+        fflush(ssl_keylog_iob);
+    PZ_Unlock(ssl_keylog_lock);
 #endif
 }
 
 /* called from ssl3_SendClientSecondRound
  *             ssl3_HandleClientHello
  *             ssl3_HandleFinished
  */
 static SECStatus
--- a/lib/ssl/sslimpl.h
+++ b/lib/ssl/sslimpl.h
@@ -1238,16 +1238,17 @@ struct sslSelfEncryptKeysStr {
     PK11SymKey *macKey;
 };
 typedef struct sslSelfEncryptKeysStr sslSelfEncryptKeys;
 
 extern char ssl_debug;
 extern char ssl_trace;
 extern FILE *ssl_trace_iob;
 extern FILE *ssl_keylog_iob;
+extern PZLock *ssl_keylog_lock;
 extern PRUint32 ssl3_sid_timeout;
 extern PRUint32 ssl_ticket_lifetime;
 extern PRUint32 ssl_max_early_data_size;
 
 extern const char *const ssl3_cipherName[];
 
 extern sslSessionIDLookupFunc ssl_sid_lookup;
 extern sslSessionIDCacheFunc ssl_sid_cache;
--- a/lib/ssl/sslsock.c
+++ b/lib/ssl/sslsock.c
@@ -119,16 +119,17 @@ PRBool locksEverDisabled; /* implicitly 
 PRBool ssl_force_locks;   /* implicitly PR_FALSE */
 int ssl_lock_readers = 1; /* default true. */
 char ssl_debug;
 char ssl_trace;
 FILE *ssl_trace_iob;
 
 #ifdef NSS_ALLOW_SSLKEYLOGFILE
 FILE *ssl_keylog_iob;
+PZLock *ssl_keylog_lock;
 #endif
 
 char lockStatus[] = "Locks are ENABLED.  ";
 #define LOCKSTATUS_OFFSET 10 /* offset of ENABLED */
 
 /* SRTP_NULL_HMAC_SHA1_80 and SRTP_NULL_HMAC_SHA1_32 are not implemented. */
 static const PRUint16 srtpCiphers[] = {
     SRTP_AES128_CM_HMAC_SHA1_80,
@@ -3539,16 +3540,22 @@ ssl_SetDefaultsFromEnvironment(void)
             if (!ssl_keylog_iob) {
                 SSL_TRACE(("SSL: failed to open key log file"));
             } else {
                 if (ftell(ssl_keylog_iob) == 0) {
                     fputs("# SSL/TLS secrets log file, generated by NSS\n",
                           ssl_keylog_iob);
                 }
                 SSL_TRACE(("SSL: logging SSL/TLS secrets to %s", ev));
+                ssl_keylog_lock = PR_NewLock();
+                if (!ssl_keylog_lock) {
+                    SSL_TRACE(("SSL: failed to create key log lock"));
+                    fclose(ssl_keylog_iob);
+                    ssl_keylog_iob = NULL;
+                }
             }
         }
 #endif
         ev = PR_GetEnvSecure("SSLFORCELOCKS");
         if (ev && ev[0] == '1') {
             ssl_force_locks = PR_TRUE;
             ssl_defaults.noLocks = 0;
             strcpy(lockStatus + LOCKSTATUS_OFFSET, "FORCED.  ");