bug 1492188 - avoid using the directory service off the main thread when loading loadable roots r=jcj

Differential Revision: https://phabricator.services.mozilla.com/D6692

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dana Keeler 2018-09-27 22:45:56 +00:00
Родитель c4b29e1ba9
Коммит 6004dbc02b
1 изменённых файлов: 47 добавлений и 19 удалений

Просмотреть файл

@ -777,13 +777,15 @@ nsNSSComponent::GetEnterpriseRoots(nsIX509CertList** enterpriseRoots)
class LoadLoadableRootsTask final : public Runnable class LoadLoadableRootsTask final : public Runnable
{ {
public: public:
explicit LoadLoadableRootsTask(nsNSSComponent* nssComponent, LoadLoadableRootsTask(nsNSSComponent* nssComponent,
bool importEnterpriseRoots, bool importEnterpriseRoots,
uint32_t familySafetyMode) uint32_t familySafetyMode,
Vector<nsCString>&& possibleLoadableRootsLocations)
: Runnable("LoadLoadableRootsTask") : Runnable("LoadLoadableRootsTask")
, mNSSComponent(nssComponent) , mNSSComponent(nssComponent)
, mImportEnterpriseRoots(importEnterpriseRoots) , mImportEnterpriseRoots(importEnterpriseRoots)
, mFamilySafetyMode(familySafetyMode) , mFamilySafetyMode(familySafetyMode)
, mPossibleLoadableRootsLocations(std::move(possibleLoadableRootsLocations))
{ {
MOZ_ASSERT(nssComponent); MOZ_ASSERT(nssComponent);
} }
@ -798,6 +800,7 @@ private:
RefPtr<nsNSSComponent> mNSSComponent; RefPtr<nsNSSComponent> mNSSComponent;
bool mImportEnterpriseRoots; bool mImportEnterpriseRoots;
uint32_t mFamilySafetyMode; uint32_t mFamilySafetyMode;
Vector<nsCString> mPossibleLoadableRootsLocations;
nsCOMPtr<nsIThread> mThread; nsCOMPtr<nsIThread> mThread;
}; };
@ -988,6 +991,8 @@ nsNSSComponent::CheckForSmartCardChanges()
static nsresult static nsresult
GetNSS3Directory(nsCString& result) GetNSS3Directory(nsCString& result)
{ {
MOZ_ASSERT(NS_IsMainThread());
UniquePRString nss3Path( UniquePRString nss3Path(
PR_GetLibraryFilePathname(MOZ_DLL_PREFIX "nss3" MOZ_DLL_SUFFIX, PR_GetLibraryFilePathname(MOZ_DLL_PREFIX "nss3" MOZ_DLL_SUFFIX,
reinterpret_cast<PRFuncPtr>(NSS_Initialize))); reinterpret_cast<PRFuncPtr>(NSS_Initialize)));
@ -1032,6 +1037,8 @@ GetNSS3Directory(nsCString& result)
static nsresult static nsresult
GetDirectoryPath(const char* directoryKey, nsCString& result) GetDirectoryPath(const char* directoryKey, nsCString& result)
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIProperties> directoryService( nsCOMPtr<nsIProperties> directoryService(
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
if (!directoryService) { if (!directoryService) {
@ -1060,20 +1067,24 @@ GetDirectoryPath(const char* directoryKey, nsCString& result)
#endif #endif
} }
// The loadable roots library is probably in the same directory we loaded the
nsresult // NSS shared library from, but in some cases it may be elsewhere. This function
LoadLoadableRootsTask::LoadLoadableRoots() // enumerates and returns the possible locations as nsCStrings.
static nsresult
ListPossibleLoadableRootsLocations(
Vector<nsCString>& possibleLoadableRootsLocations)
{ {
// Find the best Roots module for our purposes. MOZ_ASSERT(NS_IsMainThread());
// Prefer the application's installation directory, if (!NS_IsMainThread()) {
// but also ensure the library is at least the version we expect. return NS_ERROR_NOT_SAME_THREAD;
Vector<nsCString> possibleCKBILocations; }
// First try in the directory where we've already loaded // First try in the directory where we've already loaded
// MOZ_DLL_PREFIX nss3 MOZ_DLL_SUFFIX, since that's likely to be correct. // MOZ_DLL_PREFIX nss3 MOZ_DLL_SUFFIX, since that's likely to be correct.
nsAutoCString nss3Dir; nsAutoCString nss3Dir;
nsresult rv = GetNSS3Directory(nss3Dir); nsresult rv = GetNSS3Directory(nss3Dir);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
if (!possibleCKBILocations.append(std::move(nss3Dir))) { if (!possibleLoadableRootsLocations.append(std::move(nss3Dir))) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
} else { } else {
@ -1085,7 +1096,7 @@ LoadLoadableRootsTask::LoadLoadableRoots()
nsAutoCString currentProcessDir; nsAutoCString currentProcessDir;
rv = GetDirectoryPath(NS_XPCOM_CURRENT_PROCESS_DIR, currentProcessDir); rv = GetDirectoryPath(NS_XPCOM_CURRENT_PROCESS_DIR, currentProcessDir);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
if (!possibleCKBILocations.append(std::move(currentProcessDir))) { if (!possibleLoadableRootsLocations.append(std::move(currentProcessDir))) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
} else { } else {
@ -1095,7 +1106,7 @@ LoadLoadableRootsTask::LoadLoadableRoots()
nsAutoCString greDir; nsAutoCString greDir;
rv = GetDirectoryPath(NS_GRE_DIR, greDir); rv = GetDirectoryPath(NS_GRE_DIR, greDir);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
if (!possibleCKBILocations.append(std::move(greDir))) { if (!possibleLoadableRootsLocations.append(std::move(greDir))) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
} else { } else {
@ -1104,14 +1115,21 @@ LoadLoadableRootsTask::LoadLoadableRoots()
// As a last resort, this will cause the library loading code to use the OS' // As a last resort, this will cause the library loading code to use the OS'
// default library search path. // default library search path.
nsAutoCString emptyString; nsAutoCString emptyString;
if (!possibleCKBILocations.append(std::move(emptyString))) { if (!possibleLoadableRootsLocations.append(std::move(emptyString))) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
for (const auto& possibleCKBILocation : possibleCKBILocations) { return NS_OK;
if (mozilla::psm::LoadLoadableRoots(possibleCKBILocation)) { }
MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("loaded CKBI from %s",
possibleCKBILocation.get())); nsresult
LoadLoadableRootsTask::LoadLoadableRoots()
{
for (const auto& possibleLocation : mPossibleLoadableRootsLocations) {
if (mozilla::psm::LoadLoadableRoots(possibleLocation)) {
MOZ_LOG(gPIPNSSLog,
LogLevel::Debug,
("loaded CKBI from %s", possibleLocation.get()));
return NS_OK; return NS_OK;
} }
} }
@ -1487,6 +1505,8 @@ nsNSSComponent::setEnabledTLSVersions()
static void static void
SetNSSDatabaseCacheModeAsAppropriate() SetNSSDatabaseCacheModeAsAppropriate()
{ {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIFile> profileFile; nsCOMPtr<nsIFile> profileFile;
nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(profileFile)); getter_AddRefs(profileFile));
@ -1964,8 +1984,16 @@ nsNSSComponent::InitializeNSS()
false); false);
uint32_t familySafetyMode = Preferences::GetUint(kFamilySafetyModePref, uint32_t familySafetyMode = Preferences::GetUint(kFamilySafetyModePref,
kFamilySafetyModeDefault); kFamilySafetyModeDefault);
Vector<nsCString> possibleLoadableRootsLocations;
rv = ListPossibleLoadableRootsLocations(possibleLoadableRootsLocations);
if (NS_FAILED(rv)) {
return rv;
}
RefPtr<LoadLoadableRootsTask> loadLoadableRootsTask( RefPtr<LoadLoadableRootsTask> loadLoadableRootsTask(
new LoadLoadableRootsTask(this, importEnterpriseRoots, familySafetyMode)); new LoadLoadableRootsTask(this,
importEnterpriseRoots,
familySafetyMode,
std::move(possibleLoadableRootsLocations)));
rv = loadLoadableRootsTask->Dispatch(); rv = loadLoadableRootsTask->Dispatch();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;