Fix keystore wifi concurrency issue.

Keystore was conceptually single threaded. Even with the introduction of
Keymaster workers it was always assumed that the service dispatcher
thread was single threaded. The wifi keystore service, however, calls
into the keystore service concurrently.

This patch adds a lock around all keystore service entry points to make
sure all dispatcher executions are serialised despite being called from
both the binder and hwbinder service thread.

Bug: 128810613
Bug: 129145334
Bug: 128774635
Bug: 130045583
Bug: 131622568
Test: Regressions tested with Keystore CTS test suite.
Merged-In: I8c5602d2c2cb1dd9423df713037e99b247cee71f
Change-Id: I8c5602d2c2cb1dd9423df713037e99b247cee71f
(cherry picked from commit 1d898d107cdda93620301dc6c9d0f823229cee8c)
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 4f1277d..bf6589d 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -62,6 +62,8 @@
 bool isAuthenticationBound(const hidl_vec<KeyParameter>& params) {
     return !containsTag(params, Tag::NO_AUTH_REQUIRED);
 }
+#define KEYSTORE_SERVICE_LOCK \
+	std::lock_guard<decltype(keystoreServiceMutex_)> keystore_lock(keystoreServiceMutex_)
 
 std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
     struct stat sbuf;
@@ -129,6 +131,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::getState(int32_t userId) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_GET_STATE)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -138,6 +141,7 @@
 
 KeyStoreServiceReturnCode KeyStoreService::get(const String16& name, int32_t uid,
                                                hidl_vec<uint8_t>* item) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t targetUid = getEffectiveUid(uid);
     if (!checkBinderPermission(P_GET, targetUid)) {
         return ResponseCode::PERMISSION_DENIED;
@@ -168,6 +172,7 @@
 KeyStoreServiceReturnCode KeyStoreService::insert(const String16& name,
                                                   const hidl_vec<uint8_t>& item, int targetUid,
                                                   int32_t flags) {
+    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     auto result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -185,6 +190,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::del(const String16& name, int targetUid) {
+    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_DELETE, targetUid)) {
         return ResponseCode::PERMISSION_DENIED;
@@ -209,6 +215,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::exist(const String16& name, int targetUid) {
+    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_EXIST, targetUid)) {
         return ResponseCode::PERMISSION_DENIED;
@@ -220,6 +227,7 @@
 
 KeyStoreServiceReturnCode KeyStoreService::list(const String16& prefix, int targetUid,
                                                 Vector<String16>* matches) {
+    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_LIST, targetUid)) {
         return ResponseCode::PERMISSION_DENIED;
@@ -234,6 +242,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::reset() {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_RESET)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -245,6 +254,7 @@
 
 KeyStoreServiceReturnCode KeyStoreService::onUserPasswordChanged(int32_t userId,
                                                                  const String16& password) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_PASSWORD)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -280,6 +290,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::onUserAdded(int32_t userId, int32_t parentId) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_USER_CHANGED)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -302,6 +313,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::onUserRemoved(int32_t userId) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_USER_CHANGED)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -311,6 +323,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::lock(int32_t userId) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_LOCK)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -326,6 +339,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::unlock(int32_t userId, const String16& pw) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_UNLOCK)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -352,6 +366,7 @@
 }
 
 bool KeyStoreService::isEmpty(int32_t userId) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_IS_EMPTY)) {
         return false;
     }
@@ -362,6 +377,7 @@
 KeyStoreServiceReturnCode KeyStoreService::generate(const String16& name, int32_t targetUid,
                                                     int32_t keyType, int32_t keySize, int32_t flags,
                                                     Vector<sp<KeystoreArg>>* args) {
+    KEYSTORE_SERVICE_LOCK;
     targetUid = getEffectiveUid(targetUid);
     auto result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -437,6 +453,7 @@
                                                   const hidl_vec<uint8_t>& data, int targetUid,
                                                   int32_t flags) {
 
+    KEYSTORE_SERVICE_LOCK;
     const uint8_t* ptr = &data[0];
 
     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, data.size()));
@@ -473,6 +490,7 @@
 
 KeyStoreServiceReturnCode KeyStoreService::sign(const String16& name, const hidl_vec<uint8_t>& data,
                                                 hidl_vec<uint8_t>* out) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_SIGN)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -482,6 +500,7 @@
 KeyStoreServiceReturnCode KeyStoreService::verify(const String16& name,
                                                   const hidl_vec<uint8_t>& data,
                                                   const hidl_vec<uint8_t>& signature) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkBinderPermission(P_VERIFY)) {
         return ResponseCode::PERMISSION_DENIED;
     }
@@ -501,6 +520,7 @@
  */
 KeyStoreServiceReturnCode KeyStoreService::get_pubkey(const String16& name,
                                                       hidl_vec<uint8_t>* pubKey) {
+    KEYSTORE_SERVICE_LOCK;
     ExportResult result;
     exportKey(name, KeyFormat::X509, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF, &result);
     if (!result.resultCode.isOk()) {
@@ -513,6 +533,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::grant(const String16& name, int32_t granteeUid) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
     if (!result.isOk()) {
@@ -531,6 +552,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
     if (!result.isOk()) {
@@ -549,6 +571,7 @@
 }
 
 int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t targetUid = getEffectiveUid(uid);
     if (!checkBinderPermission(P_GET, targetUid)) {
         ALOGW("permission denied for %d: getmtime", targetUid);
@@ -582,6 +605,7 @@
 // TODO(tuckeris): This is dead code, remove it.  Don't bother copying over key characteristics here
 KeyStoreServiceReturnCode KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid,
                                                      const String16& destKey, int32_t destUid) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     pid_t spid = IPCThreadState::self()->getCallingPid();
     if (!has_permission(callingUid, P_DUPLICATE, spid)) {
@@ -642,10 +666,12 @@
 }
 
 int32_t KeyStoreService::is_hardware_backed(const String16& keyType) {
+    KEYSTORE_SERVICE_LOCK;
     return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
 }
 
 KeyStoreServiceReturnCode KeyStoreService::clear_uid(int64_t targetUid64) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t targetUid = getEffectiveUid(targetUid64);
     if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
         return ResponseCode::PERMISSION_DENIED;
@@ -683,6 +709,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::addRngEntropy(const hidl_vec<uint8_t>& entropy) {
+    KEYSTORE_SERVICE_LOCK;
     const auto& device = mKeyStore->getDevice();
     return KS_HANDLE_HIDL_ERROR(device->addRngEntropy(entropy));
 }
@@ -692,6 +719,7 @@
                                                        const hidl_vec<uint8_t>& entropy, int uid,
                                                        int flags,
                                                        KeyCharacteristics* outCharacteristics) {
+    KEYSTORE_SERVICE_LOCK;
     // TODO(jbires): remove this getCallingUid call upon implementation of b/25646100
     uid_t originalUid = IPCThreadState::self()->getCallingUid();
     uid = getEffectiveUid(uid);
@@ -787,6 +815,7 @@
 KeyStoreService::getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
                                        const hidl_vec<uint8_t>& appData, int32_t uid,
                                        KeyCharacteristics* outCharacteristics) {
+    KEYSTORE_SERVICE_LOCK;
     if (!outCharacteristics) {
         return ErrorCode::UNEXPECTED_NULL_POINTER;
     }
@@ -856,6 +885,7 @@
 KeyStoreService::importKey(const String16& name, const hidl_vec<KeyParameter>& params,
                            KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid, int flags,
                            KeyCharacteristics* outCharacteristics) {
+    KEYSTORE_SERVICE_LOCK;
     uid = getEffectiveUid(uid);
     KeyStoreServiceReturnCode rc =
         checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -941,6 +971,7 @@
 void KeyStoreService::exportKey(const String16& name, KeyFormat format,
                                 const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
                                 int32_t uid, ExportResult* result) {
+    KEYSTORE_SERVICE_LOCK;
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -1009,6 +1040,7 @@
                             bool pruneable, const hidl_vec<KeyParameter>& params,
                             const hidl_vec<uint8_t>& entropy, int32_t uid,
                             OperationResult* result) {
+    KEYSTORE_SERVICE_LOCK;
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
@@ -1172,6 +1204,7 @@
 
 void KeyStoreService::update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
                              const hidl_vec<uint8_t>& data, OperationResult* result) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkAllowedOperationParams(params)) {
         result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return;
@@ -1224,6 +1257,7 @@
 void KeyStoreService::finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
                              const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
                              OperationResult* result) {
+    KEYSTORE_SERVICE_LOCK;
     if (!checkAllowedOperationParams(params)) {
         result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return;
@@ -1283,6 +1317,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::abort(const sp<IBinder>& token) {
+    KEYSTORE_SERVICE_LOCK;
     km_device_t dev;
     uint64_t handle;
     KeyPurpose purpose;
@@ -1298,6 +1333,7 @@
 }
 
 bool KeyStoreService::isOperationAuthorized(const sp<IBinder>& token) {
+    KEYSTORE_SERVICE_LOCK;
     km_device_t dev;
     uint64_t handle;
     const KeyCharacteristics* characteristics;
@@ -1314,6 +1350,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::addAuthToken(const uint8_t* token, size_t length) {
+    KEYSTORE_SERVICE_LOCK;
     // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
     // receive a HardwareAuthToken, rather than an opaque byte array.
 
@@ -1370,6 +1407,7 @@
 KeyStoreServiceReturnCode KeyStoreService::attestKey(const String16& name,
                                                      const hidl_vec<KeyParameter>& params,
                                                      hidl_vec<hidl_vec<uint8_t>>* outChain) {
+    KEYSTORE_SERVICE_LOCK;
     if (!outChain) {
         return ErrorCode::OUTPUT_PARAMETER_NULL;
     }
@@ -1418,6 +1456,7 @@
 
 KeyStoreServiceReturnCode KeyStoreService::attestDeviceIds(const hidl_vec<KeyParameter>& params,
                                                            hidl_vec<hidl_vec<uint8_t>>* outChain) {
+    KEYSTORE_SERVICE_LOCK;
     if (!outChain) {
         return ErrorCode::OUTPUT_PARAMETER_NULL;
     }
@@ -1500,6 +1539,7 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::onDeviceOffBody() {
+    KEYSTORE_SERVICE_LOCK;
     // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
     mAuthTokenTable.onDeviceOffBody();
     return ResponseCode::NO_ERROR;
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 3b4ef85..8b2f1cb 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -249,6 +249,17 @@
                                              const AuthorizationSet& params, Blob* blob);
 
     ::KeyStore* mKeyStore;
+
+    /**
+     * This mutex locks keystore operations from concurrent execution.
+     * The keystore service has always been conceptually single threaded. Even with the introduction
+     * of keymaster workers, it was assumed that the dispatcher thread executes exclusively on
+     * certain code paths. With the introduction of wifi Keystore service in the keystore process
+     * this assumption no longer holds as the hwbinder thread servicing this interface makes
+     * functions (rather than IPC) calls into keystore. This mutex protects the keystore logic
+     * from concurrent execution.
+     */
+    std::recursive_mutex keystoreServiceMutex_;
     OperationMap mOperationMap;
     keystore::AuthTokenTable mAuthTokenTable;
     KeystoreKeymasterEnforcement enforcement_policy;