diff options
author | Edwin Wong <edwinwong@google.com> | 2021-04-02 20:14:49 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-04-02 20:14:49 +0000 |
commit | 00b96f0a78ae23da72f46b0181a61a19198fce77 (patch) | |
tree | 863c48351589a095596586d6fd2d58fc44f5a238 | |
parent | ee714b664f9eff311b42de04769159b6edd8ddad (diff) | |
parent | 3b1141d44f448ea9a528ff8af8f128686c35039d (diff) |
Merge "Fix UAF in clearkey service's MemoryFileSystem" into rvc-dev
5 files changed, 25 insertions, 3 deletions
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp index a194416c7f..c6afa60f96 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp +++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp @@ -37,7 +37,7 @@ cc_defaults { relative_install_path: "hw", - cflags: ["-Wall", "-Werror"], + cflags: ["-Wall", "-Werror", "-Wthread-safety"], shared_libs: [ "android.hardware.drm@1.0", diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp index 97a62be7f1..6f69110d50 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp @@ -220,6 +220,7 @@ Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope, if (requestString.find(kOfflineLicense) != std::string::npos) { std::string emptyResponse; std::string keySetIdString(keySetId.begin(), keySetId.end()); + Mutex::Autolock lock(mFileHandleLock); if (!mFileHandle.StoreLicense(keySetIdString, DeviceFiles::kLicenseStateReleasing, emptyResponse)) { @@ -335,6 +336,7 @@ bool DrmPlugin::makeKeySetId(std::string* keySetId) { } *keySetId = kKeySetIdPrefix + ByteArrayToHexString( reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size()); + Mutex::Autolock lock(mFileHandleLock); if (mFileHandle.LicenseExists(*keySetId)) { // collision, regenerate ALOGV("Retry generating KeySetId"); @@ -392,6 +394,7 @@ Return<void> DrmPlugin::provideKeyResponse( if (status == Status::OK) { if (isOfflineLicense) { if (isRelease) { + Mutex::Autolock lock(mFileHandleLock); mFileHandle.DeleteLicense(keySetId); mSessionLibrary->destroySession(session); } else { @@ -400,6 +403,7 @@ Return<void> DrmPlugin::provideKeyResponse( return Void(); } + Mutex::Autolock lock(mFileHandleLock); bool ok = mFileHandle.StoreLicense( keySetId, DeviceFiles::kLicenseStateActive, @@ -454,6 +458,7 @@ Return<Status> DrmPlugin::restoreKeys( DeviceFiles::LicenseState licenseState; std::string offlineLicense; Status status = Status::OK; + Mutex::Autolock lock(mFileHandleLock); if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()), &licenseState, &offlineLicense)) { ALOGE("Failed to restore offline license"); @@ -705,6 +710,8 @@ Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) { } Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) { + Mutex::Autolock lock(mFileHandleLock); + std::vector<std::string> licenseNames = mFileHandle.ListLicenses(); std::vector<KeySetId> keySetIds; if (mMockError != Status_V1_2::OK) { @@ -725,6 +732,7 @@ Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) { return toStatus_1_0(mMockError); } std::string licenseName(keySetId.begin(), keySetId.end()); + Mutex::Autolock lock(mFileHandleLock); if (mFileHandle.DeleteLicense(licenseName)) { return Status::OK; } @@ -733,6 +741,8 @@ Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) { Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId, getOfflineLicenseState_cb _hidl_cb) { + Mutex::Autolock lock(mFileHandleLock); + std::string licenseName(keySetId.begin(), keySetId.end()); DeviceFiles::LicenseState state; std::string license; diff --git a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp index 2dcd00fb27..d29acac30a 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp @@ -24,11 +24,13 @@ std::string MemoryFileSystem::GetFileName(const std::string& path) { } bool MemoryFileSystem::FileExists(const std::string& fileName) const { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(fileName); return result != mMemoryFileSystem.end(); } ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(fileName); if (result != mMemoryFileSystem.end()) { return static_cast<ssize_t>(result->second.getFileSize()); @@ -40,6 +42,7 @@ ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const { std::vector<std::string> MemoryFileSystem::ListFiles() const { std::vector<std::string> list; + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); for (const auto& filename : mMemoryFileSystem) { list.push_back(filename.first); } @@ -48,6 +51,7 @@ std::vector<std::string> MemoryFileSystem::ListFiles() const { size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) { std::string key = GetFileName(path); + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(key); if (result != mMemoryFileSystem.end()) { std::string serializedHashFile = result->second.getContent(); @@ -61,6 +65,7 @@ size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) { size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memoryFile) { std::string key = GetFileName(path); + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(key); if (result != mMemoryFileSystem.end()) { mMemoryFileSystem.erase(key); @@ -70,6 +75,7 @@ size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memory } bool MemoryFileSystem::RemoveFile(const std::string& fileName) { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(fileName); if (result != mMemoryFileSystem.end()) { mMemoryFileSystem.erase(result); @@ -81,6 +87,7 @@ bool MemoryFileSystem::RemoveFile(const std::string& fileName) { } bool MemoryFileSystem::RemoveAllFiles() { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); mMemoryFileSystem.clear(); return mMemoryFileSystem.empty(); } diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h index 076beb8a0d..894985bd1b 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h +++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h @@ -416,7 +416,8 @@ private: mMockError = Status_V1_2::OK; } - DeviceFiles mFileHandle; + DeviceFiles mFileHandle GUARDED_BY(mFileHandleLock); + Mutex mFileHandleLock; Mutex mSecureStopLock; CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin); diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h index bcd9fd631a..6ac0e2c4bb 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h +++ b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h @@ -5,7 +5,9 @@ #ifndef CLEARKEY_MEMORY_FILE_SYSTEM_H_ #define CLEARKEY_MEMORY_FILE_SYSTEM_H_ +#include <android-base/thread_annotations.h> #include <map> +#include <mutex> #include <string> #include "ClearKeyTypes.h" @@ -49,10 +51,12 @@ class MemoryFileSystem { size_t Write(const std::string& pathName, const MemoryFile& memoryFile); private: + mutable std::mutex mMemoryFileSystemLock; + // License file name is made up of a unique keySetId, therefore, // the filename can be used as the key to locate licenses in the // memory file system. - std::map<std::string, MemoryFile> mMemoryFileSystem; + std::map<std::string, MemoryFile> mMemoryFileSystem GUARDED_BY(mMemoryFileSystemLock); std::string GetFileName(const std::string& path); |