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 | 6889557362e8d542c99d4138fa0c0a98e8ffb9a7 (patch) | |
tree | 1f7b651d5b55506184c117a7362af662483c8626 | |
parent | 7df29ccb132cdec678b172f2c3b9cdefb30b7027 (diff) | |
parent | 9ba33b35860503814ed02bf5bcf5ff24e4056f6d (diff) |
Merge "[RESTRICT AUTOMERGE] Fix UAF in clearkey service's MemoryFileSystem" into qt-dev
5 files changed, 24 insertions, 3 deletions
diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp index e91e918b1d..fdb18d07e1 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 15ebf78621..8150c1dcc8 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp @@ -213,6 +213,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)) { @@ -328,6 +329,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"); @@ -380,6 +382,7 @@ Return<void> DrmPlugin::provideKeyResponse( if (status == Status::OK) { if (isOfflineLicense) { if (isRelease) { + Mutex::Autolock lock(mFileHandleLock); mFileHandle.DeleteLicense(keySetId); } else { if (!makeKeySetId(&keySetId)) { @@ -387,6 +390,7 @@ Return<void> DrmPlugin::provideKeyResponse( return Void(); } + Mutex::Autolock lock(mFileHandleLock); bool ok = mFileHandle.StoreLicense( keySetId, DeviceFiles::kLicenseStateActive, @@ -441,6 +445,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"); @@ -691,6 +696,7 @@ 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) { @@ -711,6 +717,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; } @@ -719,6 +726,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 526f019d21..7ea58e07a9 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; + Mutex mFileHandleLock; + DeviceFiles mFileHandle GUARDED_BY(mFileHandleLock); 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); |