Last Comment Bug 679140 - Do all SSL error processing on the main thread
: Do all SSL error processing on the main thread
Status: RESOLVED FIXED
:
Product: Core
Classification: Components
Component: Security: PSM (show other bugs)
: Trunk
: All All
: -- critical (vote)
: ---
Assigned To: Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
:
Mentors:
: 679036 (view as bug list)
Depends on: 682329
Blocks: 436379 619198 650858 675221 678440 678547 679035
  Show dependency treegraph
 
Reported: 2011-08-15 14:25 PDT by Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
Modified: 2011-10-25 21:16 PDT (History)
9 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---
-
-


Attachments
Handle SSL errors on the main thread (23.49 KB, patch)
2011-08-15 23:53 PDT, Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
no flags Details | Diff | Splinter Review
Handle all SSL errors (including cert errors) on the main thread (29.29 KB, patch)
2011-09-23 10:18 PDT, Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
honzab.moz: review+
Details | Diff | Splinter Review
Do all SSL error processing on the main thread [v2] (33.72 KB, patch)
2011-10-02 05:39 PDT, Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
honzab.moz: review+
Details | Diff | Splinter Review
Do all SSL error processing on the main thread [v3] (25.23 KB, patch)
2011-10-05 23:29 PDT, Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
no flags Details | Diff | Splinter Review
Do all SSL error processing on the main thread [v3] (31.13 KB, patch)
2011-10-06 00:08 PDT, Brian Smith (:briansmith, :bsmith, use NEEDINFO?)
brian: review+
brian: checkin+
Details | Diff | Splinter Review

Description Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-08-15 14:25:29 PDT
+++ This bug was initially created as a clone of Bug #679036 +++

Currently, we use many XPCOM proxies in the processing of SSL errors (e.g. reporting errors). Instead of replacing each XPCOM proxy usage with a separate runnable that gets sync-dispatched to the main thread, let's move all of this processing to a single runnable that gets dispatched to the main thread.
Comment 1 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-08-15 23:53:55 PDT
Created attachment 553387 [details] [diff] [review]
Handle SSL errors on the main thread

You probably have to apply the patch for bug 679144 before applying this one, as the removal of EnsureDocShellDependentStuff depends on the removal of GetPreviousCert() in that bug.
Comment 2 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-09-18 23:25:06 PDT
*** Bug 679036 has been marked as a duplicate of this bug. ***
Comment 3 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-09-23 10:18:32 PDT
Created attachment 562086 [details] [diff] [review]
Handle all SSL errors (including cert errors) on the main thread

This patch removes the XPCOM proxies that are using during the processing of SSL errors, including certificate errors. You need to apply this patch first:
https://bugzilla.mozilla.org/attachment.cgi?id=562083&action=edit
Comment 4 Honza Bambas (:mayhemer) 2011-09-27 16:02:34 PDT
Comment on attachment 562086 [details] [diff] [review]
Handle all SSL errors (including cert errors) on the main thread

Review of attachment 562086 [details] [diff] [review]:
-----------------------------------------------------------------

r=honzab with following comments.

::: security/manager/ssl/src/nsCertOverrideService.cpp
@@ +154,5 @@
>  
> +  nsCOMPtr<nsIObserverService> observerService =
> +      mozilla::services::GetObserverService();
> +  if (!observerService)
> +    return NS_ERROR_FAILURE;

Too hard failure.  Use the previous conditional code please.

@@ +158,5 @@
> +    return NS_ERROR_FAILURE;
> +
> +  observerService->AddObserver(this, "profile-before-change", PR_TRUE);
> +  observerService->AddObserver(this, "profile-do-change", PR_TRUE);
> +  observerService->AddObserver(this, "shutdown-cleanse", PR_TRUE);

Registering for "shutdown-cleanse" topic is non-sense.  It's an arg to profile-before-change notification, correctly handled in Observe().

@@ +164,4 @@
>    // cache mSettingsFile
>    NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mSettingsFile));
> +  if (!mSettingsFile)
> +    return NS_ERROR_FAILURE;

I think this service should work even w/o a profile.  You should not hard fail Init() on failure of getting the profile dir.

::: security/manager/ssl/src/nsNSSComponent.cpp
@@ -1700,5 @@
> -      if (NS_FAILED(rv)) {
> -        nsPSMInitPanic::SetPanic();
> -        return rv;
> -      }
> -    }

Hmm... added in bug 619201.

I'd a bit more prefer to leave this code here, but up to you.  It has no affect on the start-up time anyway, I think.

I think we should have a mechanism to ensure nss component be initialized on the main thread even it may get called from a background thread (e.g. in a worker using DOMCrypto, if it's accessible to it).

::: security/manager/ssl/src/nsNSSIOLayer.cpp
@@ +1383,1 @@
>    if (socketInfo->GetCanceled()) {

Value of this getter may get changed on either SSL thread or network thread.  On the network thread only when the socket associated with the info is not "busy" (i.e. the socket is the only one currently processed on the SSL thread).  It means it is safe to read it here on the main thread because the socket is now busy and no code can modify it.

Some comment like this (feel free to rephrase my poor english) would be useful here.

@@ +1388,3 @@
>    }
>  
>    if (nsSSLThread::stoppedOrStopping()) {

This is read on some places w/o a lock anyway, so it is probably ok to read it here as well.

@@ +1854,5 @@
>      
>      // This is the common place where we trigger an error message on a SSL socket.
>      // This might be reached at any time of the connection.
>      if (!wantRetry && (IS_SSL_ERROR(err) || IS_SEC_ERROR(err))) {
> +      nsCOMPtr<SyncRunnableBase> runnable = new SSLErrorRunnable(socketInfo, err);

nsRefPtr please.

@@ +3202,5 @@
> +  PRBool const mHasCertNameMismatch;
> +  SECStatus mRv;
> +  PRErrorCode mErrorCodeToReport;
> +  nsXPIDLCString mHostname;
> +};

Might be nice to group and comment members (read: event arguments) that are in, in/out (if any) and out only.

@@ +3313,5 @@
> +                            defaultErrorCodeToReport);
> +
> +    // now grab the host name to pass to the STS Service
> +    nsrv = infoObject->GetHostName(getter_Copies(runnable->mHostname));
> +    if (!NS_SUCCEEDED(nsrv)) {

NS_FAILED ?

@@ +3355,5 @@
> +    return;
> + 
> +  PRErrorCode errorCodeMismatch = 0;
> +  PRErrorCode errorCodeTrust = 0;
> +  PRErrorCode errorCodeExpired = 0;

Use SECSuccess instead of 0 ?

@@ +3524,5 @@
>    NS_ConvertASCIItoUTF16 hostU(hostString);
>    NS_ConvertASCIItoUTF16 hostWithPortU(hostWithPortString);
>  
> +  nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
> +  if (NS_SUCCEEDED(nsrv)) {

Can you just add a comment why this is needed ?  I think nss component is already up when we get here.
Comment 5 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-01 19:52:10 PDT
(In reply to Honza Bambas (:mayhemer) from comment #4)
> ::: security/manager/ssl/src/nsCertOverrideService.cpp
> @@ +154,5 @@
> >  
> > +  nsCOMPtr<nsIObserverService> observerService =
> > +      mozilla::services::GetObserverService();
> > +  if (!observerService)
> > +    return NS_ERROR_FAILURE;
> 
> Too hard failure.  Use the previous conditional code please.

We really need the observer service to operate correctly and securely. Otherwise, we may end up reading/writing to the wrong override files after a profile switch. Really, mozilla::services::GetObserverService() must never fail; otherwise, I am sure many, many things break.

> > +  observerService->AddObserver(this, "profile-before-change", PR_TRUE);
> > +  observerService->AddObserver(this, "profile-do-change", PR_TRUE);
> > +  observerService->AddObserver(this, "shutdown-cleanse", PR_TRUE);
> 
> Registering for "shutdown-cleanse" topic is non-sense.  It's an arg to
> profile-before-change notification, correctly handled in Observe().

Agreed. I will make this change.

> 
> @@ +164,4 @@
> >    // cache mSettingsFile
> >    NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mSettingsFile));
> > +  if (!mSettingsFile)
> > +    return NS_ERROR_FAILURE;
> 
> I think this service should work even w/o a profile.  You should not hard
> fail Init() on failure of getting the profile dir.

OK. I will try to make the service operate correctly without a profile. 

> ::: security/manager/ssl/src/nsNSSComponent.cpp
> @@ -1700,5 @@
> > -      if (NS_FAILED(rv)) {
> > -        nsPSMInitPanic::SetPanic();
> > -        return rv;
> > -      }
> > -    }
> 
> Hmm... added in bug 619201.
> 
> I'd a bit more prefer to leave this code here, but up to you.  It has no
> affect on the start-up time anyway, I think.

This patch is basically an alternative solution to bug 619201, and that patch caused bug 650858. This patch will fix both of those bugs.

> > +  PRErrorCode errorCodeMismatch = 0;
> > +  PRErrorCode errorCodeTrust = 0;
> > +  PRErrorCode errorCodeExpired = 0;
> 
> Use SECSuccess instead of 0 ?

SECSuccess is of type SECStatus, not PRErrorCode. That is why I changed it to 0.

> > +  nsCOMPtr<nsINSSComponent> inss = do_GetService(kNSSComponentCID, &nsrv);
> > +  if (NS_SUCCEEDED(nsrv)) {
> 
> Can you just add a comment why this is needed ?  I think nss component is
> already up when we get here.

Yes, the NSS component is already up. Simply, we need a reference to it to pass to a function a few lines afterward.

Thanks for r+ing the patch. I am going to upload another version for you to review because of the small disagreements/misunderstandings above.
Comment 6 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-02 05:39:22 PDT
Created attachment 564046 [details] [diff] [review]
Do all SSL error processing on the main thread [v2]

Review comments addressed. I changed the error handling in the cert override service so that it will work without a profile, and in such a way that it will not ever miss a profile change event. I also changed the external error reporting to behave like it did before.
Comment 7 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-02 05:41:16 PDT
The patch queue for this patch should look like this:
psm-remove-default-ssl-error-UI.patch (bug 682329)
psm-remove-certerror-test.patch (bug 682329)
psm-runnable.patch (bug 675221)
psm-handle-ssl-and-cert-errors-on-main-thread.patch

This patch will not work without the preceeding patches.
Comment 8 Benjamin Smedberg AWAY UNTIL 2-AUG-2016 [:bsmedberg] 2011-10-02 05:41:43 PDT
Note that we never change profiles in a process: we start out with no profile, we start a profile, and then we shut down. It is not necessary to support switching profile directories.
Comment 9 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-02 13:43:40 PDT
Ben, I would be very happy to be able to assume that. However, I was told Seamonkey does implement same-process profile switching. Also, Dan Mills and Ben Adida mentioned that they were considering profile switching for "Sign in to the Browser." Regardless, PSM has always tried to support it, and it wasn't hard to fix the patch to do what we need.
Comment 10 Benjamin Smedberg AWAY UNTIL 2-AUG-2016 [:bsmedberg] 2011-10-03 14:08:30 PDT
We absolutely don't support it in any application nowadays and haven't since seamonkey switched to the new addons manager and toolkit/xre startup sequence, so it's really dead/untested code.
Comment 11 Honza Bambas (:mayhemer) 2011-10-04 12:55:18 PDT
Comment on attachment 564046 [details] [diff] [review]
Do all SSL error processing on the main thread [v2]

Review of attachment 564046 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks.  Looks good.

r=honzab with one question answered.

::: security/manager/ssl/src/nsCertOverrideService.cpp
@@ +159,5 @@
> +  // attempt to read/write any settings file. Otherwise, we would end up
> +  // reading/writing the wrong settings file after a profile change.
> +  if (observerService) {
> +    observerService->AddObserver(this, "profile-before-change", true);
> +    observerService->AddObserver(this, "profile-do-change", true);

Maybe add a new line here to make direct call to Observe more visible.

::: security/manager/ssl/src/nsNSSIOLayer.cpp
@@ +552,5 @@
>  {
> +  if (!NS_IsMainThread()) {
> +    NS_NOTREACHED("nsNSSSocketInfo::GetInterface called off the main thread");
> +    return NS_ERROR_NOT_SAME_THREAD;
> +  }

The question: Can you explain what changes in the patch ensure this will never happen or is it actually necessary to ensure this?

@@ +1792,5 @@
>    
>    return false;
>  }
>  
> +class SSLErrorRunnable : public SyncRunnableBase

What about to call this e.g. SyncHandleSSLError to reflect that it calls nsHandleSSLError function?

@@ +3242,4 @@
>      return SECFailure;
>  
> +  if (defaultErrorCodeToReport == 0) {
> +    NS_NOTREACHED("No error code set during certificate validation failure.");

Please use here rather NS_ERROR or NS_WARNING ; i'd prefer the letter because you recover from this state in the following code.  However, this may indicate an error (critical? - you might know better then me) in the cert validation code, so it should not be loosen to warning but rather be an error then..

@@ +3480,5 @@
>    nsCOMPtr<nsIStrictTransportSecurityService> stss
>      = do_GetService(NS_STSSERVICE_CONTRACTID);
> +  if (stss) {
> +    nsrv = stss->IsStsHost(mHostname, &strictTransportSecurityEnabled);
> +    if (!NS_SUCCEEDED(nsrv))

NS_FAILED ?

@@ +3482,5 @@
> +  if (stss) {
> +    nsrv = stss->IsStsHost(mHostname, &strictTransportSecurityEnabled);
> +    if (!NS_SUCCEEDED(nsrv))
> +      return; // use default rv and errorCodeToReport
> +  }

Looks like when we don't have STS service (in that case creation of the proxy object fails) the old code fails (result is SECFailure).  But yours passes.

Sorry I didn't spot this in the previous version of the patch.
Comment 12 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-05 23:29:49 PDT
Created attachment 565140 [details] [diff] [review]
Do all SSL error processing on the main thread [v3]

I moved the changes to nsNSSSocketInfo::GetInterface to the relevant patch in bug 675221, where they belong. I did not rename the SSLErrorRunnable class in order to keep its name analogous to CertErrorRunnable.

I also rebased the patch on current mozilla-central (without requiring any PR_TRUE/PR_FALSE -> true/false patches), because this will need to be checked into mozilla-aurora to fix bug 650858.
Comment 13 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-06 00:08:20 PDT
Created attachment 565145 [details] [diff] [review]
Do all SSL error processing on the main thread [v3]
Comment 14 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-06 00:10:51 PDT
Comment on attachment 565145 [details] [diff] [review]
Do all SSL error processing on the main thread [v3]

Carrying over r+.
Comment 15 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-07 00:10:26 PDT
Comment on attachment 565145 [details] [diff] [review]
Do all SSL error processing on the main thread [v3]

https://hg.mozilla.org/mozilla-central/rev/eb25f2b8c126
Comment 16 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-07 00:21:24 PDT
Tracking Firefox 8 to fix bug 650858.
Comment 17 Brian Smith (:briansmith, :bsmith, use NEEDINFO?) 2011-10-07 00:25:37 PDT
Tracking Firefox 8 and 9 to fix bug 650858.

A simpler alternative to taking this is to back out the patch for bug 619201 like we did for Firefox 6 and 7.
Comment 18 christian 2011-10-25 21:16:16 PDT
---------------------------------[ Triage Comment ]---------------------------------

We decided to instead back out the patch for bug 619201 like we did for Firefox 6 and 7. The backouts are in bug 650858 and we shouldn't need them on mozilla-central / Firefox 10 because this landed there.

There is nothing to do here and no need to track.

Note You need to log in before you can comment on or make changes to this bug.