Bug 873615 - Make certificate verification avoid addrefing JS-wrapped listeners off the main thread. r=bsmith
authorJosh Matthews <josh@joshmatthews.net>
Fri, 17 May 2013 15:28:18 -0400
changeset 133465 a7aa62774568267a866946e3a61234f93802bdb8
parent 133464 8323f6dbe1a1e76e52fc40715c6615a2c7c96eaf
child 133466 4ad62762835b689fd19ba18ed075df012f8e5822
push id24753
push userryanvm@gmail.com
push dateFri, 31 May 2013 00:50:14 +0000
treeherdermozilla-central@3c6f2394995d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmith
bugs873615
milestone24.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 873615 - Make certificate verification avoid addrefing JS-wrapped listeners off the main thread. r=bsmith
security/manager/ssl/src/nsCertVerificationThread.cpp
security/manager/ssl/src/nsNSSCertificate.cpp
security/manager/ssl/src/nsVerificationJob.h
--- a/security/manager/ssl/src/nsCertVerificationThread.cpp
+++ b/security/manager/ssl/src/nsCertVerificationThread.cpp
@@ -1,40 +1,41 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsCertVerificationThread.h"
 #include "nsThreadUtils.h"
+#include "nsProxyRelease.h"
 
 using namespace mozilla;
 
 nsCertVerificationThread *nsCertVerificationThread::verification_thread_singleton;
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsCertVerificationResult, nsICertVerificationResult)
 
 namespace {
 class DispatchCertVerificationResult : public nsRunnable
 {
 public:
-  DispatchCertVerificationResult(nsICertVerificationListener* aListener,
+  DispatchCertVerificationResult(const nsMainThreadPtrHandle<nsICertVerificationListener>& aListener,
                                  nsIX509Cert3* aCert,
                                  nsICertVerificationResult* aResult)
     : mListener(aListener)
     , mCert(aCert)
     , mResult(aResult)
   { }
 
   NS_IMETHOD Run() {
     mListener->Notify(mCert, mResult);
     return NS_OK;
   }
 
 private:
-  nsCOMPtr<nsICertVerificationListener> mListener;
+  nsMainThreadPtrHandle<nsICertVerificationListener> mListener;
   nsCOMPtr<nsIX509Cert3> mCert;
   nsCOMPtr<nsICertVerificationResult> mResult;
 };
 } // anonymous namespace
 
 void nsCertVerificationJob::Run()
 {
   if (!mListener || !mCert)
--- a/security/manager/ssl/src/nsNSSCertificate.cpp
+++ b/security/manager/ssl/src/nsNSSCertificate.cpp
@@ -32,16 +32,17 @@
 #include "nsUnicharUtils.h"
 #include "nsThreadUtils.h"
 #include "nsCertVerificationThread.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIObjectInputStream.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsXULAppAPI.h"
 #include "ScopedNSSTypes.h"
+#include "nsProxyRelease.h"
 
 #include "nspr.h"
 #include "certdb.h"
 #include "secerr.h"
 #include "nssb64.h"
 #include "secasn1.h"
 #include "secder.h"
 #include "ssl.h"
@@ -1402,23 +1403,25 @@ nsNSSCertificate::GetUsagesArray(bool lo
     return NS_ERROR_OUT_OF_MEMORY;
   *_count = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNSSCertificate::RequestUsagesArrayAsync(nsICertVerificationListener *aResultListener)
 {
+  NS_ENSURE_TRUE(NS_IsMainThread(), NS_ERROR_NOT_SAME_THREAD);
+
   if (!aResultListener)
     return NS_ERROR_FAILURE;
   
   nsCertVerificationJob *job = new nsCertVerificationJob;
 
   job->mCert = this;
-  job->mListener = aResultListener;
+  job->mListener = new nsMainThreadPtrHolder<nsICertVerificationListener>(aResultListener);
 
   nsresult rv = nsCertVerificationThread::addJob(job);
   if (NS_FAILED(rv))
     delete job;
 
   return rv;
 }
 
--- a/security/manager/ssl/src/nsVerificationJob.h
+++ b/security/manager/ssl/src/nsVerificationJob.h
@@ -8,29 +8,30 @@
 #define _INC_NSVERIFICATIONJOB_H
 
 #include "nspr.h"
 
 #include "nsIX509Cert.h"
 #include "nsIX509Cert3.h"
 #include "nsICMSMessage.h"
 #include "nsICMSMessage2.h"
+#include "nsProxyRelease.h"
 
 class nsBaseVerificationJob
 {
 public:
   virtual ~nsBaseVerificationJob() {}
   virtual void Run() = 0;
 };
 
 class nsCertVerificationJob : public nsBaseVerificationJob
 {
 public:
   nsCOMPtr<nsIX509Cert> mCert;
-  nsCOMPtr<nsICertVerificationListener> mListener;
+  nsMainThreadPtrHandle<nsICertVerificationListener> mListener;
 
   void Run();
 };
 
 class nsCertVerificationResult : public nsICertVerificationResult
 {
 public:
   nsCertVerificationResult();