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

Commit f1065779 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "transcoding: trust MediaProvider to set uid for jobs"

parents 51304028 c37bdfeb
Loading
Loading
Loading
Loading
+33 −17
Original line number Diff line number Diff line
@@ -23,12 +23,16 @@
#include <inttypes.h>
#include <media/TranscodingClientManager.h>
#include <media/TranscodingRequest.h>
#include <media/TranscodingUidPolicy.h>
#include <private/android_filesystem_config.h>
#include <utils/Log.h>
#include <utils/String16.h>
namespace android {

static_assert(sizeof(ClientIdType) == sizeof(void*), "ClientIdType should be pointer-sized");

static constexpr const char* MEDIA_PROVIDER_PKG_NAME = "com.google.android.providers.media.module";

using ::aidl::android::media::BnTranscodingClient;
using ::aidl::android::media::IMediaTranscodingService;  // For service error codes
using ::aidl::android::media::TranscodingJobParcel;
@@ -51,20 +55,6 @@ std::map<ClientIdType, std::shared_ptr<TranscodingClientManager::ClientImpl>>
            errorCode,                                \
            String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, ##__VA_ARGS__))

// Can MediaTranscoding service trust the caller based on the calling UID?
// TODO(hkuang): Add MediaProvider's UID.
static bool isTrustedCallingUid(uid_t uid) {
    switch (uid) {
    case AID_ROOT:  // root user
    case AID_SYSTEM:
    case AID_SHELL:
    case AID_MEDIA:  // mediaserver
        return true;
    default:
        return false;
    }
}

/**
 * ClientImpl implements a single client and contains all its information.
 */
@@ -143,7 +133,7 @@ Status TranscodingClientManager::ClientImpl::submitRequest(
        in_clientUid = callingUid;
    } else if (in_clientUid < 0) {
        return Status::ok();
    } else if (in_clientUid != callingUid && !isTrustedCallingUid(callingUid)) {
    } else if (in_clientUid != callingUid && !owner->isTrustedCallingUid(callingUid)) {
        ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
              "(don't trust callingUid %d)",
              in_clientPid, in_clientUid, callingUid);
@@ -160,7 +150,7 @@ Status TranscodingClientManager::ClientImpl::submitRequest(
        in_clientPid = callingPid;
    } else if (in_clientPid < 0) {
        return Status::ok();
    } else if (in_clientPid != callingPid && !isTrustedCallingUid(callingUid)) {
    } else if (in_clientPid != callingPid && !owner->isTrustedCallingUid(callingUid)) {
        ALOGE("MediaTranscodingService::registerClient rejected (clientPid %d, clientUid %d) "
              "(don't trust callingUid %d)",
              in_clientPid, in_clientUid, callingUid);
@@ -267,8 +257,18 @@ void TranscodingClientManager::BinderDiedCallback(void* cookie) {

TranscodingClientManager::TranscodingClientManager(
        const std::shared_ptr<SchedulerClientInterface>& scheduler)
      : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)), mJobScheduler(scheduler) {
      : mDeathRecipient(AIBinder_DeathRecipient_new(BinderDiedCallback)),
        mJobScheduler(scheduler),
        mMediaProviderUid(-1) {
    ALOGD("TranscodingClientManager started");
    uid_t mpuid;
    if (TranscodingUidPolicy::getUidForPackage(String16(MEDIA_PROVIDER_PKG_NAME), mpuid) ==
        NO_ERROR) {
        ALOGI("Found MediaProvider uid: %d", mpuid);
        mMediaProviderUid = mpuid;
    } else {
        ALOGW("Couldn't get uid for MediaProvider.");
    }
}

TranscodingClientManager::~TranscodingClientManager() {
@@ -299,6 +299,22 @@ void TranscodingClientManager::dumpAllClients(int fd, const Vector<String16>& ar
    write(fd, result.string(), result.size());
}

bool TranscodingClientManager::isTrustedCallingUid(uid_t uid) {
    if (uid > 0 && uid == mMediaProviderUid) {
        return true;
    }

    switch (uid) {
    case AID_ROOT:  // root user
    case AID_SYSTEM:
    case AID_SHELL:
    case AID_MEDIA:  // mediaserver
        return true;
    default:
        return false;
    }
}

status_t TranscodingClientManager::addClient(
        const std::shared_ptr<ITranscodingClientCallback>& callback, const std::string& clientName,
        const std::string& opPackageName, std::shared_ptr<ITranscodingClient>* outClient) {
+15 −0
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@
#include <android/content/pm/IPackageManagerNative.h>
#include <binder/ActivityManager.h>
#include <binder/IServiceManager.h>
#include <binder/PermissionController.h>
#include <cutils/misc.h>  // FIRST_APPLICATION_UID
#include <cutils/multiuser.h>
#include <inttypes.h>
#include <media/TranscodingUidPolicy.h>
#include <utils/Log.h>
@@ -133,6 +135,19 @@ bool TranscodingUidPolicy::getNamesForUids(const std::vector<int32_t>& uids,
    return true;
}

//static
status_t TranscodingUidPolicy::getUidForPackage(String16 packageName, /*inout*/ uid_t& uid) {
    PermissionController pc;
    uid = pc.getPackageUid(packageName, 0);
    if (uid <= 0) {
        ALOGE("Unknown package: '%s'", String8(packageName).string());
        return BAD_VALUE;
    }

    uid = multiuser_get_uid(0 /*userId*/, uid);
    return NO_ERROR;
}

TranscodingUidPolicy::TranscodingUidPolicy()
      : mAm(std::make_shared<ActivityManager>()),
        mUidObserver(new UidObserver(this)),
+4 −0
Original line number Diff line number Diff line
@@ -86,6 +86,9 @@ private:
    // Only allow MediaTranscodingService and unit tests to instantiate.
    TranscodingClientManager(const std::shared_ptr<SchedulerClientInterface>& scheduler);

    // Checks if a user is trusted (and allowed to submit jobs on behalf of other uids)
    bool isTrustedCallingUid(uid_t uid);

    /**
     * Removes an existing client from the manager.
     *
@@ -106,6 +109,7 @@ private:
    ::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;

    std::shared_ptr<SchedulerClientInterface> mJobScheduler;
    uid_t mMediaProviderUid;

    static std::atomic<ClientIdType> sCookieCounter;
    static std::mutex sCookie2ClientLock;
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ public:
    // ~UidPolicyInterface

    static bool getNamesForUids(const std::vector<int32_t>& uids, std::vector<std::string>* names);
    static status_t getUidForPackage(String16 packageName, /*inout*/ uid_t& uid);

private:
    void onUidStateChanged(uid_t uid, int32_t procState);