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

Commit 00b96f0a authored by Edwin Wong's avatar Edwin Wong Committed by Android (Google) Code Review
Browse files

Merge "Fix UAF in clearkey service's MemoryFileSystem" into rvc-dev

parents ee714b66 3b1141d4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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",
+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");
@@ -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;
+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);