platform_system_security/keystore/operation.cpp
Max Bires 091ed1b975 Reducing amount of files created in dropbox for keystore
This change will reduce the number of files written to dropbox for the
purposes of keystore logging. Previously, if a ton of operations were
being done, a file would be created for each operation which led to
spamming of the dropbox directory.

Now, all equivalent operations are counted and only one copy is sent
along with the corresponding count over the time period of an hour. This
limits the number of files keystore can write to dropbox to 24 a day,
and will reduce the possible size of files since redundant operations
aren't being written.

Bug: 117823210
Bug: 110988360
Test: atest cts/tests/tests/keystore/src/android/keystore/cts
Change-Id: I79367aa7a8eb3679aace2058e128d06e513e25ea
2019-01-15 18:47:42 +00:00

102 lines
3.6 KiB
C++

/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "KeystoreOperation"
#include "operation.h"
#include <algorithm>
#include <android-base/logging.h>
#include <mutex>
namespace keystore {
OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
: mDeathRecipient(deathRecipient) {}
sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
const sp<Keymaster>& dev, const sp<IBinder>& appToken,
KeyCharacteristics&& characteristics,
const hidl_vec<KeyParameter>& params, bool pruneable) {
sp<IBinder> token = new ::android::BBinder();
mMap.emplace(token, std::make_shared<Operation>(handle, keyid, purpose, dev,
std::move(characteristics), appToken, params));
if (pruneable) mLru.push_back(token);
if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) appToken->linkToDeath(mDeathRecipient);
mAppTokenMap[appToken].push_back(token);
return token;
}
std::shared_ptr<Operation> OperationMap::getOperation(const sp<IBinder>& token) {
auto entry = mMap.find(token);
if (entry == mMap.end()) return {};
auto op = entry->second;
updateLru(token);
return op;
}
void OperationMap::updateLru(const sp<IBinder>& token) {
auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
if (lruEntry != mLru.end()) {
mLru.erase(lruEntry);
mLru.push_back(token);
}
}
std::shared_ptr<Operation> OperationMap::removeOperation(const sp<IBinder>& token,
bool wasSuccessful) {
auto entry = mMap.find(token);
if (entry == mMap.end()) return {};
auto op = entry->second;
operationUploader.uploadOpAsProto(*op, wasSuccessful);
mMap.erase(entry);
auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
if (lruEntry != mLru.end()) mLru.erase(lruEntry);
removeOperationTracking(token, op->appToken);
return op;
}
void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
auto appEntry = mAppTokenMap.find(appToken);
if (appEntry == mAppTokenMap.end()) {
ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
return;
}
auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
appEntry->second.erase(tokenEntry);
// Stop listening for death if all operations tied to the token have finished.
if (appEntry->second.size() == 0) {
appToken->unlinkToDeath(mDeathRecipient);
mAppTokenMap.erase(appEntry);
}
}
sp<IBinder> OperationMap::getOldestPruneableOperation() {
if (mLru.size() == 0) return {};
return {mLru.front()};
}
std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
auto appEntry = mAppTokenMap.find(appToken);
if (appEntry == mAppTokenMap.end()) return {};
return appEntry->second;
}
} // namespace keystore