Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 314fb15e authored by Edwin Wong's avatar Edwin Wong Committed by Automerger Merge Worker
Browse files

Merge "Fix UAF in clearkey service's MemoryFileSystem" into rvc-dev am: 00b96f0a am: 3f0b90d0

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/av/+/13462731

Change-Id: Id96259f14122ab03821343deb949846776788839
parents 73bc14e3 3f0b90d0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ cc_defaults {

    relative_install_path: "hw",

    cflags: ["-Wall", "-Werror"],
    cflags: ["-Wall", "-Werror", "-Wthread-safety"],

    shared_libs: [
        "android.hardware.drm@1.0",
+10 −0
Original line number Diff line number Diff line
@@ -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");
@@ -704,6 +709,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) {
@@ -724,6 +731,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;
    }
@@ -732,6 +740,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;
+7 −0
Original line number Diff line number Diff line
@@ -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();
}
+2 −1
Original line number Diff line number Diff line
@@ -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);
+5 −1
Original line number Diff line number Diff line
@@ -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);