diff options
author | Shawn Willden <swillden@google.com> | 2015-11-02 21:06:28 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2015-11-02 21:06:28 +0000 |
commit | 733539776541fa51bddf2d38fb57e556d563d9af (patch) | |
tree | 40fa57edfeb0e6e5b0496b9b48ca61dc4aa270fb | |
parent | bc22f8d63e2ca24ee4ee9d61258d6704bc78724b (diff) | |
parent | ddab0bb51320af9f277d98a4e36e77ea527503e5 (diff) | |
download | android_system_security-733539776541fa51bddf2d38fb57e556d563d9af.tar.gz android_system_security-733539776541fa51bddf2d38fb57e556d563d9af.tar.bz2 android_system_security-733539776541fa51bddf2d38fb57e556d563d9af.zip |
Limit maximum number of concurrent keystore operations.
am: ddab0bb513
* commit 'ddab0bb51320af9f277d98a4e36e77ea527503e5':
Limit maximum number of concurrent keystore operations.
-rw-r--r-- | keystore/keystore.cpp | 46 | ||||
-rw-r--r-- | keystore/operation.h | 1 |
2 files changed, 35 insertions, 12 deletions
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp index bb5a411..e466466 100644 --- a/keystore/keystore.cpp +++ b/keystore/keystore.cpp @@ -79,6 +79,7 @@ #define KEY_SIZE ((NAME_MAX - 15) / 2) #define VALUE_SIZE 32768 #define PASSWORD_SIZE VALUE_SIZE +const size_t MAX_OPERATIONS = 15; using keymaster::SoftKeymasterDevice; @@ -2689,23 +2690,26 @@ public: } keymaster_key_param_set_t outParams = {NULL, 0}; + + // If there are more than MAX_OPERATIONS, abort the oldest operation that was started as + // pruneable. + while (mOperationMap.getOperationCount() >= MAX_OPERATIONS) { + ALOGD("Reached or exceeded concurrent operations limit"); + if (!pruneOperation()) { + break; + } + } + err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle); + if (err != KM_ERROR_OK) { + ALOGE("Got error %d from begin()", err); + } // If there are too many operations abort the oldest operation that was // started as pruneable and try again. while (err == KM_ERROR_TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) { - sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation(); - ALOGD("Ran out of operation handles, trying to prune %p", oldest.get()); - - // We mostly ignore errors from abort() below because all we care about is whether at - // least one pruneable operation has been removed. - size_t op_count_before = mOperationMap.getPruneableOperationCount(); - int abort_error = abort(oldest); - size_t op_count_after = mOperationMap.getPruneableOperationCount(); - if (op_count_after >= op_count_before) { - // Failed to create space for a new operation. Bail to avoid an infinite loop. - ALOGE("Failed to remove pruneable operation %p, error: %d", - oldest.get(), abort_error); + ALOGE("Ran out of operation handles"); + if (!pruneOperation()) { break; } err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle); @@ -2909,6 +2913,24 @@ private: static const int32_t UID_SELF = -1; /** + * Prune the oldest pruneable operation. + */ + inline bool pruneOperation() { + sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation(); + ALOGD("Trying to prune operation %p", oldest.get()); + size_t op_count_before_abort = mOperationMap.getOperationCount(); + // We mostly ignore errors from abort() because all we care about is whether at least + // one operation has been removed. + int abort_error = abort(oldest); + if (mOperationMap.getOperationCount() >= op_count_before_abort) { + ALOGE("Failed to abort pruneable operation %p, error: %d", oldest.get(), + abort_error); + return false; + } + return true; + } + + /** * Get the effective target uid for a binder operation that takes an * optional uid as the target. */ diff --git a/keystore/operation.h b/keystore/operation.h index 01c4dbe..d8d1b18 100644 --- a/keystore/operation.h +++ b/keystore/operation.h @@ -57,6 +57,7 @@ public: const keymaster_key_characteristics_t** outCharacteristics); bool removeOperation(sp<IBinder> token); bool hasPruneableOperation() const; + size_t getOperationCount() const { return mMap.size(); } size_t getPruneableOperationCount() const; bool getOperationAuthToken(sp<IBinder> token, const hw_auth_token_t** outToken); bool setOperationAuthToken(sp<IBinder> token, const hw_auth_token_t* authToken); |