Bug 1915008 - leak mResultTask if dispatch fails in certificate verification r=jschanck
Differential Revision: https://phabricator.services.mozilla.com/D221381
This commit is contained in:
@@ -741,17 +741,15 @@ SSLServerCertVerificationJob::Run() {
|
||||
// Runs on a cert verification thread and only on parent process.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
MOZ_LOG(
|
||||
gPIPNSSLog, LogLevel::Debug,
|
||||
("[%" PRIx64 "] SSLServerCertVerificationJob::Run\n", mAddrForLogging));
|
||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||
("[%" PRIx64 "] SSLServerCertVerificationJob::Run", mAddrForLogging));
|
||||
|
||||
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
|
||||
if (!certVerifier) {
|
||||
PR_SetError(SEC_ERROR_NOT_INITIALIZED, 0);
|
||||
// We can't release this off the STS thread because some parts of it
|
||||
// are not threadsafe. Just leak the mResultTask
|
||||
// are not threadsafe. Just leak mResultTask.
|
||||
Unused << mResultTask.forget();
|
||||
return NS_OK;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
TimeStamp jobStartTime = TimeStamp::Now();
|
||||
@@ -761,7 +759,7 @@ SSLServerCertVerificationJob::Run() {
|
||||
bool madeOCSPRequests = false;
|
||||
nsTArray<nsTArray<uint8_t>> builtChainBytesArray;
|
||||
nsTArray<uint8_t> certBytes(mPeerCertChain.ElementAt(0).Clone());
|
||||
Result rv = AuthCertificate(
|
||||
Result result = AuthCertificate(
|
||||
*certVerifier, mPinArg, certBytes, mPeerCertChain, mHostName,
|
||||
mOriginAttributes, mStapledOCSPResponse, mSCTsFromTLSExtension, mDCInfo,
|
||||
mProviderFlags, mTime, mCertVerifierFlags, builtChainBytesArray, evStatus,
|
||||
@@ -769,25 +767,30 @@ SSLServerCertVerificationJob::Run() {
|
||||
madeOCSPRequests);
|
||||
|
||||
TimeDuration elapsed = TimeStamp::Now() - jobStartTime;
|
||||
if (rv == Success) {
|
||||
if (result == Success) {
|
||||
mozilla::glean::cert_verification_time::success.AccumulateRawDuration(
|
||||
elapsed);
|
||||
Telemetry::Accumulate(Telemetry::SSL_CERT_ERROR_OVERRIDES, 1);
|
||||
|
||||
mResultTask->Dispatch(
|
||||
nsresult rv = mResultTask->Dispatch(
|
||||
std::move(builtChainBytesArray), std::move(mPeerCertChain),
|
||||
TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus(
|
||||
certificateTransparencyInfo),
|
||||
evStatus, true, 0,
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET,
|
||||
isCertChainRootBuiltInRoot, mProviderFlags, madeOCSPRequests);
|
||||
return NS_OK;
|
||||
if (NS_FAILED(rv)) {
|
||||
// We can't release this off the STS thread because some parts of it
|
||||
// are not threadsafe. Just leak mResultTask.
|
||||
Unused << mResultTask.forget();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
mozilla::glean::cert_verification_time::failure.AccumulateRawDuration(
|
||||
elapsed);
|
||||
|
||||
PRErrorCode error = MapResultToPRErrorCode(rv);
|
||||
PRErrorCode error = MapResultToPRErrorCode(result);
|
||||
nsITransportSecurityInfo::OverridableErrorCategory overridableErrorCategory =
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET;
|
||||
nsCOMPtr<nsIX509Cert> cert(new nsNSSCertificate(std::move(certBytes)));
|
||||
@@ -796,16 +799,22 @@ SSLServerCertVerificationJob::Run() {
|
||||
overridableErrorCategory);
|
||||
|
||||
// NB: finalError may be 0 here, in which the connection will continue.
|
||||
mResultTask->Dispatch(
|
||||
nsresult rv = mResultTask->Dispatch(
|
||||
std::move(builtChainBytesArray), std::move(mPeerCertChain),
|
||||
nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE,
|
||||
EVStatus::NotEV, false, finalError, overridableErrorCategory,
|
||||
// If the certificate verifier returned Result::ERROR_BAD_CERT_DOMAIN, a
|
||||
// chain was built, so isCertChainRootBuiltInRoot is valid and
|
||||
// potentially useful. Otherwise, assume no chain was built.
|
||||
rv == Result::ERROR_BAD_CERT_DOMAIN ? isCertChainRootBuiltInRoot : false,
|
||||
result == Result::ERROR_BAD_CERT_DOMAIN ? isCertChainRootBuiltInRoot
|
||||
: false,
|
||||
mProviderFlags, madeOCSPRequests);
|
||||
return NS_OK;
|
||||
if (NS_FAILED(rv)) {
|
||||
// We can't release this off the STS thread because some parts of it
|
||||
// are not threadsafe. Just leak mResultTask.
|
||||
Unused << mResultTask.forget();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Takes information needed for cert verification, does some consistency
|
||||
@@ -1029,7 +1038,7 @@ SSLServerCertVerificationResult::SSLServerCertVerificationResult(
|
||||
nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET),
|
||||
mProviderFlags(0) {}
|
||||
|
||||
void SSLServerCertVerificationResult::Dispatch(
|
||||
nsresult SSLServerCertVerificationResult::Dispatch(
|
||||
nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
@@ -1075,11 +1084,12 @@ void SSLServerCertVerificationResult::Dispatch(
|
||||
if (!stsTarget) {
|
||||
// This has to be released on STS; just leak it
|
||||
Unused << mSocketControl.forget();
|
||||
return;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = stsTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv),
|
||||
"Failed to dispatch SSLServerCertVerificationResult");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
||||
@@ -44,15 +44,15 @@ class BaseSSLServerCertVerificationResult {
|
||||
public:
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
|
||||
virtual void Dispatch(nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
[[nodiscard]] virtual nsresult Dispatch(
|
||||
nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus,
|
||||
EVStatus aEVStatus, bool aSucceeded,
|
||||
PRErrorCode aFinalError,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError,
|
||||
nsITransportSecurityInfo::OverridableErrorCategory
|
||||
aOverridableErrorCategory,
|
||||
bool aIsBuiltCertChainRootBuiltInRoot,
|
||||
uint32_t aProviderFlags, bool aMadeOCSPRequests) = 0;
|
||||
bool aIsBuiltCertChainRootBuiltInRoot, uint32_t aProviderFlags,
|
||||
bool aMadeOCSPRequests) = 0;
|
||||
};
|
||||
|
||||
// Dispatched to the STS thread to notify the infoObject of the verification
|
||||
@@ -70,7 +70,8 @@ class SSLServerCertVerificationResult final
|
||||
|
||||
explicit SSLServerCertVerificationResult(CommonSocketControl* socketControl);
|
||||
|
||||
void Dispatch(nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
[[nodiscard]] nsresult Dispatch(
|
||||
nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError,
|
||||
|
||||
@@ -46,11 +46,16 @@ ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifySSLServerCertFinished(
|
||||
certBytesArray.AppendElement(std::move(cert.data()));
|
||||
}
|
||||
|
||||
mResultTask->Dispatch(std::move(certBytesArray), std::move(mPeerCertChain),
|
||||
aCertTransparencyStatus, aEVStatus, aSucceeded,
|
||||
aFinalError, aOverridableErrorCategory,
|
||||
aIsBuiltCertChainRootBuiltInRoot, mProviderFlags,
|
||||
aMadeOCSPRequests);
|
||||
nsresult rv = mResultTask->Dispatch(
|
||||
std::move(certBytesArray), std::move(mPeerCertChain),
|
||||
aCertTransparencyStatus, aEVStatus, aSucceeded, aFinalError,
|
||||
aOverridableErrorCategory, aIsBuiltCertChainRootBuiltInRoot,
|
||||
mProviderFlags, aMadeOCSPRequests);
|
||||
if (NS_FAILED(rv)) {
|
||||
// We can't release this off the STS thread because some parts of it are
|
||||
// not threadsafe. Just leak mResultTask.
|
||||
Unused << mResultTask.forget();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ class IPCServerCertVerificationResult final
|
||||
VerifySSLServerCertParent* aParent)
|
||||
: mTarget(aTarget), mParent(aParent) {}
|
||||
|
||||
void Dispatch(nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
[[nodiscard]] nsresult Dispatch(
|
||||
nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
bool aSucceeded, PRErrorCode aFinalError,
|
||||
@@ -73,7 +74,7 @@ class IPCServerCertVerificationResult final
|
||||
RefPtr<VerifySSLServerCertParent> mParent;
|
||||
};
|
||||
|
||||
void IPCServerCertVerificationResult::Dispatch(
|
||||
nsresult IPCServerCertVerificationResult::Dispatch(
|
||||
nsTArray<nsTArray<uint8_t>>&& aBuiltChain,
|
||||
nsTArray<nsTArray<uint8_t>>&& aPeerCertChain,
|
||||
uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus,
|
||||
@@ -89,7 +90,7 @@ void IPCServerCertVerificationResult::Dispatch(
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nrv = mTarget->Dispatch(
|
||||
nsresult rv = mTarget->Dispatch(
|
||||
NS_NewRunnableFunction(
|
||||
"psm::VerifySSLServerCertParent::OnVerifiedSSLServerCert",
|
||||
[parent(mParent), builtCertChain{std::move(builtCertChain)},
|
||||
@@ -102,8 +103,8 @@ void IPCServerCertVerificationResult::Dispatch(
|
||||
aIsBuiltCertChainRootBuiltInRoot, aMadeOCSPRequests);
|
||||
}),
|
||||
NS_DISPATCH_NORMAL);
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(nrv));
|
||||
Unused << nrv;
|
||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
Reference in New Issue
Block a user