Index: components/os_crypt/os_crypt_linux.cc |
diff --git a/components/os_crypt/os_crypt_linux.cc b/components/os_crypt/os_crypt_linux.cc |
index 68ea402dd9a3ea1c6a2bdb9212f2cb5d17d18a92..86503382b4f43466b918746aabb6097aee847413 100644 |
--- a/components/os_crypt/os_crypt_linux.cc |
+++ b/components/os_crypt/os_crypt_linux.cc |
@@ -14,6 +14,7 @@ |
#include "base/logging.h" |
#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/synchronization/lock.h" |
#include "components/os_crypt/key_storage_linux.h" |
#include "crypto/encryptor.h" |
#include "crypto/symmetric_key.h" |
@@ -54,6 +55,9 @@ struct Cache { |
std::unique_ptr<std::string> password_v11_cache; |
bool is_key_storage_cached; |
bool is_password_v11_cached; |
+ // Guards access to |g_cache|, making lazy initialization of individual parts |
+ // thread safe. |
+ base::Lock lock; |
}; |
base::LazyInstance<Cache>::Leaky g_cache = LAZY_INSTANCE_INITIALIZER; |
@@ -68,20 +72,23 @@ KeyStorageLinux* GetKeyStorage() { |
return g_cache.Get().key_storage_cache.get(); |
} |
-// Returns a cached string of "peanuts". |
+// Returns a cached string of "peanuts". Is thread-safe. |
std::string* GetPasswordV10() { |
- if (!g_cache.Get().password_v10_cache.get()) |
+ base::AutoLock auto_lock(g_cache.Get().lock); |
+ if (!g_cache.Get().password_v10_cache.get()) { |
g_cache.Get().password_v10_cache.reset(new std::string("peanuts")); |
+ } |
return g_cache.Get().password_v10_cache.get(); |
} |
// Caches and returns the password from the KeyStorage or null if there is no |
-// service. |
+// service. Is thread-safe. |
std::string* GetPasswordV11() { |
+ base::AutoLock auto_lock(g_cache.Get().lock); |
if (!g_cache.Get().is_password_v11_cached) { |
- g_cache.Get().is_password_v11_cached = true; |
g_cache.Get().password_v11_cache.reset( |
GetKeyStorage() ? new std::string(GetKeyStorage()->GetKey()) : nullptr); |
+ g_cache.Get().is_password_v11_cached = true; |
} |
return g_cache.Get().password_v11_cache.get(); |
} |
@@ -248,13 +255,16 @@ void UseMockKeyStorageForTesting(KeyStorageLinux* (*get_key_storage_mock)(), |
if (get_key_storage_mock && get_password_v11_mock) { |
// Bypass calling KeyStorage::CreateService and caching of the key for V11 |
- g_get_password[Version::V11] = get_password_v11_mock; |
+ if (get_password_v11_mock) |
+ g_get_password[Version::V11] = get_password_v11_mock; |
// OSCrypt will determine the encryption version by checking if a |
// |KeyStorage| instance can be created. Enable V11 by returning the mock. |
- g_key_storage_provider = get_key_storage_mock; |
+ if (get_key_storage_mock) |
+ g_key_storage_provider = get_key_storage_mock; |
} else { |
// Restore real implementation |
std::copy(std::begin(get_password_save), std::end(get_password_save), |
std::begin(g_get_password)); |
+ g_key_storage_provider = &GetKeyStorage; |
} |
} |