Merge "Abort operation pruning only if it fails to make space." into mnc-dev
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 85289ad..cb948fd 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -2507,7 +2507,16 @@
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());
- if (abort(oldest) != ::NO_ERROR) {
+
+ // 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);
break;
}
err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle);
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index aa37101..4a71922 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -103,10 +103,14 @@
}
}
-bool OperationMap::hasPruneableOperation() {
+bool OperationMap::hasPruneableOperation() const {
return mLru.size() != 0;
}
+size_t OperationMap::getPruneableOperationCount() const {
+ return mLru.size();
+}
+
sp<IBinder> OperationMap::getOldestPruneableOperation() {
if (!hasPruneableOperation()) {
return sp<IBinder>(NULL);
diff --git a/keystore/operation.h b/keystore/operation.h
index 6806388..01c4dbe 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -56,7 +56,8 @@
const keymaster1_device_t** outDev,
const keymaster_key_characteristics_t** outCharacteristics);
bool removeOperation(sp<IBinder> token);
- bool hasPruneableOperation();
+ bool hasPruneableOperation() const;
+ 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);
sp<IBinder> getOldestPruneableOperation();