summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--keystore/key_store_service.cpp40
-rw-r--r--keystore/key_store_service.h11
2 files changed, 51 insertions, 0 deletions
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 4f1277de..bf6589dc 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -62,6 +62,8 @@ bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
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 @@ void KeyStoreService::binderDied(const wp<IBinder>& who) {
}
KeyStoreServiceReturnCode KeyStoreService::getState(int32_t userId) {
+ KEYSTORE_SERVICE_LOCK;
if (!checkBinderPermission(P_GET_STATE)) {
return ResponseCode::PERMISSION_DENIED;
}
@@ -138,6 +141,7 @@ KeyStoreServiceReturnCode KeyStoreService::getState(int32_t userId) {
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::get(const String16& name, int32_t uid
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::insert(const String16& name,
}
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::del(const String16& name, int targetU
}
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::exist(const String16& name, int targe
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::list(const String16& prefix, int targ
}
KeyStoreServiceReturnCode KeyStoreService::reset() {
+ KEYSTORE_SERVICE_LOCK;
if (!checkBinderPermission(P_RESET)) {
return ResponseCode::PERMISSION_DENIED;
}
@@ -245,6 +254,7 @@ KeyStoreServiceReturnCode KeyStoreService::reset() {
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::onUserPasswordChanged(int32_t userId,
}
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::onUserAdded(int32_t userId, int32_t p
}
KeyStoreServiceReturnCode KeyStoreService::onUserRemoved(int32_t userId) {
+ KEYSTORE_SERVICE_LOCK;
if (!checkBinderPermission(P_USER_CHANGED)) {
return ResponseCode::PERMISSION_DENIED;
}
@@ -311,6 +323,7 @@ KeyStoreServiceReturnCode KeyStoreService::onUserRemoved(int32_t userId) {
}
KeyStoreServiceReturnCode KeyStoreService::lock(int32_t userId) {
+ KEYSTORE_SERVICE_LOCK;
if (!checkBinderPermission(P_LOCK)) {
return ResponseCode::PERMISSION_DENIED;
}
@@ -326,6 +339,7 @@ KeyStoreServiceReturnCode KeyStoreService::lock(int32_t userId) {
}
KeyStoreServiceReturnCode KeyStoreService::unlock(int32_t userId, const String16& pw) {
+ KEYSTORE_SERVICE_LOCK;
if (!checkBinderPermission(P_UNLOCK)) {
return ResponseCode::PERMISSION_DENIED;
}
@@ -352,6 +366,7 @@ KeyStoreServiceReturnCode KeyStoreService::unlock(int32_t userId, const String16
}
bool KeyStoreService::isEmpty(int32_t userId) {
+ KEYSTORE_SERVICE_LOCK;
if (!checkBinderPermission(P_IS_EMPTY)) {
return false;
}
@@ -362,6 +377,7 @@ bool KeyStoreService::isEmpty(int32_t userId) {
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 @@ KeyStoreServiceReturnCode KeyStoreService::import(const String16& name,
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::import(const String16& name,
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::sign(const String16& name, const hidl
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::verify(const String16& name,
*/
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::get_pubkey(const String16& name,
}
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::grant(const String16& name, int32_t g
}
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 @@ KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t
}
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 @@ int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
// 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 @@ KeyStoreServiceReturnCode KeyStoreService::duplicate(const String16& srcKey, int
}
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::clear_uid(int64_t targetUid64) {
}
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 @@ KeyStoreServiceReturnCode KeyStoreService::generateKey(const String16& name,
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 @@ KeyStoreServiceReturnCode
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 @@ KeyStoreServiceReturnCode
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 @@ KeyStoreService::importKey(const String16& name, const hidl_vec<KeyParameter>& p
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 @@ void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, K
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::begin(const sp<IBinder>& appToken, const String16& name, K
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::update(const sp<IBinder>& token, const hidl_vec<KeyParamet
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 @@ void KeyStoreService::finish(const sp<IBinder>& token, const hidl_vec<KeyParamet
}
KeyStoreServiceReturnCode KeyStoreService::abort(const sp<IBinder>& token) {
+ KEYSTORE_SERVICE_LOCK;
km_device_t dev;
uint64_t handle;
KeyPurpose purpose;
@@ -1298,6 +1333,7 @@ KeyStoreServiceReturnCode KeyStoreService::abort(const sp<IBinder>& token) {
}
bool KeyStoreService::isOperationAuthorized(const sp<IBinder>& token) {
+ KEYSTORE_SERVICE_LOCK;
km_device_t dev;
uint64_t handle;
const KeyCharacteristics* characteristics;
@@ -1314,6 +1350,7 @@ bool KeyStoreService::isOperationAuthorized(const sp<IBinder>& token) {
}
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 @@ bool isDeviceIdAttestationRequested(const hidl_vec<KeyParameter>& params) {
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::attestKey(const String16& name,
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::attestDeviceIds(const hidl_vec<KeyPar
}
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 3b4ef85b..8b2f1cb0 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -249,6 +249,17 @@ class KeyStoreService : public android::BnKeystoreService, public android::IBind
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;