transcoding: trust MediaProvider to set uid for jobs
bug: 154733526
test: manually check that MediaProvider uid is obtained
successfully, and isTrustedCallingUid() is true
Change-Id: I5577adcfc1acdac343ec3d98a1e33a9fc2fe36d6
diff --git a/media/libmediatranscoding/TranscodingClientManager.cpp b/media/libmediatranscoding/TranscodingClientManager.cpp
index 3f79705..82a6dde 100644
--- a/media/libmediatranscoding/TranscodingClientManager.cpp
+++ b/media/libmediatranscoding/TranscodingClientManager.cpp
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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) {
diff --git a/media/libmediatranscoding/TranscodingUidPolicy.cpp b/media/libmediatranscoding/TranscodingUidPolicy.cpp
index f0d4945..9763921 100644
--- a/media/libmediatranscoding/TranscodingUidPolicy.cpp
+++ b/media/libmediatranscoding/TranscodingUidPolicy.cpp
@@ -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 @@
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)),
diff --git a/media/libmediatranscoding/include/media/TranscodingClientManager.h b/media/libmediatranscoding/include/media/TranscodingClientManager.h
index 015a83a..be03bc4 100644
--- a/media/libmediatranscoding/include/media/TranscodingClientManager.h
+++ b/media/libmediatranscoding/include/media/TranscodingClientManager.h
@@ -86,6 +86,9 @@
// 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 @@
::ndk::ScopedAIBinder_DeathRecipient mDeathRecipient;
std::shared_ptr<SchedulerClientInterface> mJobScheduler;
+ uid_t mMediaProviderUid;
static std::atomic<ClientIdType> sCookieCounter;
static std::mutex sCookie2ClientLock;
diff --git a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h b/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
index 42052cb..f02b591 100644
--- a/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
+++ b/media/libmediatranscoding/include/media/TranscodingUidPolicy.h
@@ -50,6 +50,7 @@
// ~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);