Home | History | Annotate | Download | only in drmserver
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 //#define LOG_NDEBUG 0
     18 #define LOG_TAG "DrmManagerService(Native)"
     19 #include <utils/Log.h>
     20 
     21 #include <private/android_filesystem_config.h>
     22 #include <media/MemoryLeakTrackUtil.h>
     23 
     24 #include <errno.h>
     25 #include <utils/threads.h>
     26 #include <binder/IServiceManager.h>
     27 #include <binder/IPCThreadState.h>
     28 #include <sys/stat.h>
     29 #include "DrmManagerService.h"
     30 #include "DrmManager.h"
     31 
     32 #include <selinux/android.h>
     33 
     34 using namespace android;
     35 
     36 static int selinux_enabled;
     37 static char *drmserver_context;
     38 static Vector<uid_t> trustedUids;
     39 
     40 const char *const DrmManagerService::drm_perm_labels[] = {
     41     "consumeRights",
     42     "setPlaybackStatus",
     43     "openDecryptSession",
     44     "closeDecryptSession",
     45     "initializeDecryptUnit",
     46     "decrypt",
     47     "finalizeDecryptUnit",
     48     "pread"
     49 };
     50 
     51 const char *DrmManagerService::get_perm_label(drm_perm_t perm) {
     52     unsigned int index = perm;
     53 
     54     if (index >= (sizeof(drm_perm_labels) / sizeof(drm_perm_labels[0]))) {
     55         ALOGE("SELinux: Failed to retrieve permission label(perm=%d).\n", perm);
     56         abort();
     57     }
     58     return drm_perm_labels[index];
     59 }
     60 
     61 bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm) {
     62     if (selinux_enabled <= 0) {
     63         return true;
     64     }
     65 
     66     char *sctx;
     67     const char *selinux_class = "drmservice";
     68     const char *str_perm = get_perm_label(perm);
     69 
     70     if (getpidcon(spid, &sctx) != 0) {
     71         ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
     72         return false;
     73     }
     74 
     75     bool allowed = (selinux_check_access(sctx, drmserver_context, selinux_class,
     76             str_perm, NULL) == 0);
     77     freecon(sctx);
     78 
     79     return allowed;
     80 }
     81 
     82 bool DrmManagerService::isProtectedCallAllowed(drm_perm_t perm) {
     83     // TODO
     84     // Following implementation is just for reference.
     85     // Each OEM manufacturer should implement/replace with their own solutions.
     86     IPCThreadState* ipcState = IPCThreadState::self();
     87     uid_t uid = ipcState->getCallingUid();
     88     pid_t spid = ipcState->getCallingPid();
     89 
     90     for (unsigned int i = 0; i < trustedUids.size(); ++i) {
     91         if (trustedUids[i] == uid) {
     92             return selinuxIsProtectedCallAllowed(spid, perm);
     93         }
     94     }
     95     return false;
     96 }
     97 
     98 void DrmManagerService::instantiate() {
     99     ALOGV("instantiate");
    100     defaultServiceManager()->addService(String16("drm.drmManager"), new DrmManagerService());
    101 
    102     if (0 >= trustedUids.size()) {
    103         // TODO
    104         // Following implementation is just for reference.
    105         // Each OEM manufacturer should implement/replace with their own solutions.
    106 
    107         // Add trusted uids here
    108         trustedUids.push(AID_MEDIA);
    109     }
    110 
    111     selinux_enabled = is_selinux_enabled();
    112     if (selinux_enabled > 0 && getcon(&drmserver_context) != 0) {
    113         ALOGE("SELinux: DrmManagerService failed to get context for DrmManagerService. Aborting.\n");
    114         abort();
    115     }
    116 
    117     union selinux_callback cb;
    118     cb.func_log = selinux_log_callback;
    119     selinux_set_callback(SELINUX_CB_LOG, cb);
    120 }
    121 
    122 DrmManagerService::DrmManagerService() :
    123         mDrmManager(NULL) {
    124     ALOGV("created");
    125     mDrmManager = new DrmManager();
    126     mDrmManager->loadPlugIns();
    127 }
    128 
    129 DrmManagerService::~DrmManagerService() {
    130     ALOGV("Destroyed");
    131     mDrmManager->unloadPlugIns();
    132     delete mDrmManager; mDrmManager = NULL;
    133 }
    134 
    135 int DrmManagerService::addUniqueId(bool isNative) {
    136     return mDrmManager->addUniqueId(isNative);
    137 }
    138 
    139 void DrmManagerService::removeUniqueId(int uniqueId) {
    140     mDrmManager->removeUniqueId(uniqueId);
    141 }
    142 
    143 void DrmManagerService::addClient(int uniqueId) {
    144     mDrmManager->addClient(uniqueId);
    145 }
    146 
    147 void DrmManagerService::removeClient(int uniqueId) {
    148     mDrmManager->removeClient(uniqueId);
    149 }
    150 
    151 status_t DrmManagerService::setDrmServiceListener(
    152             int uniqueId, const sp<IDrmServiceListener>& drmServiceListener) {
    153     ALOGV("Entering setDrmServiceListener");
    154     mDrmManager->setDrmServiceListener(uniqueId, drmServiceListener);
    155     return DRM_NO_ERROR;
    156 }
    157 
    158 DrmConstraints* DrmManagerService::getConstraints(
    159             int uniqueId, const String8* path, const int action) {
    160     ALOGV("Entering getConstraints from content");
    161     return mDrmManager->getConstraints(uniqueId, path, action);
    162 }
    163 
    164 DrmMetadata* DrmManagerService::getMetadata(int uniqueId, const String8* path) {
    165     ALOGV("Entering getMetadata from content");
    166     return mDrmManager->getMetadata(uniqueId, path);
    167 }
    168 
    169 bool DrmManagerService::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
    170     ALOGV("Entering canHandle");
    171     return mDrmManager->canHandle(uniqueId, path, mimeType);
    172 }
    173 
    174 DrmInfoStatus* DrmManagerService::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
    175     ALOGV("Entering processDrmInfo");
    176     return mDrmManager->processDrmInfo(uniqueId, drmInfo);
    177 }
    178 
    179 DrmInfo* DrmManagerService::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
    180     ALOGV("Entering acquireDrmInfo");
    181     return mDrmManager->acquireDrmInfo(uniqueId, drmInfoRequest);
    182 }
    183 
    184 status_t DrmManagerService::saveRights(
    185             int uniqueId, const DrmRights& drmRights,
    186             const String8& rightsPath, const String8& contentPath) {
    187     ALOGV("Entering saveRights");
    188     return mDrmManager->saveRights(uniqueId, drmRights, rightsPath, contentPath);
    189 }
    190 
    191 String8 DrmManagerService::getOriginalMimeType(int uniqueId, const String8& path, int fd) {
    192     ALOGV("Entering getOriginalMimeType");
    193     return mDrmManager->getOriginalMimeType(uniqueId, path, fd);
    194 }
    195 
    196 int DrmManagerService::getDrmObjectType(
    197            int uniqueId, const String8& path, const String8& mimeType) {
    198     ALOGV("Entering getDrmObjectType");
    199     return mDrmManager->getDrmObjectType(uniqueId, path, mimeType);
    200 }
    201 
    202 int DrmManagerService::checkRightsStatus(
    203             int uniqueId, const String8& path, int action) {
    204     ALOGV("Entering checkRightsStatus");
    205     return mDrmManager->checkRightsStatus(uniqueId, path, action);
    206 }
    207 
    208 status_t DrmManagerService::consumeRights(
    209             int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
    210     ALOGV("Entering consumeRights");
    211     if (!isProtectedCallAllowed(CONSUME_RIGHTS)) {
    212         return DRM_ERROR_NO_PERMISSION;
    213     }
    214     return mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
    215 }
    216 
    217 status_t DrmManagerService::setPlaybackStatus(
    218             int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
    219     ALOGV("Entering setPlaybackStatus");
    220     if (!isProtectedCallAllowed(SET_PLAYBACK_STATUS)) {
    221         return DRM_ERROR_NO_PERMISSION;
    222     }
    223     return mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
    224 }
    225 
    226 bool DrmManagerService::validateAction(
    227             int uniqueId, const String8& path,
    228             int action, const ActionDescription& description) {
    229     ALOGV("Entering validateAction");
    230     return mDrmManager->validateAction(uniqueId, path, action, description);
    231 }
    232 
    233 status_t DrmManagerService::removeRights(int uniqueId, const String8& path) {
    234     ALOGV("Entering removeRights");
    235     return mDrmManager->removeRights(uniqueId, path);
    236 }
    237 
    238 status_t DrmManagerService::removeAllRights(int uniqueId) {
    239     ALOGV("Entering removeAllRights");
    240     return mDrmManager->removeAllRights(uniqueId);
    241 }
    242 
    243 int DrmManagerService::openConvertSession(int uniqueId, const String8& mimeType) {
    244     ALOGV("Entering openConvertSession");
    245     return mDrmManager->openConvertSession(uniqueId, mimeType);
    246 }
    247 
    248 DrmConvertedStatus* DrmManagerService::convertData(
    249             int uniqueId, int convertId, const DrmBuffer* inputData) {
    250     ALOGV("Entering convertData");
    251     return mDrmManager->convertData(uniqueId, convertId, inputData);
    252 }
    253 
    254 DrmConvertedStatus* DrmManagerService::closeConvertSession(int uniqueId, int convertId) {
    255     ALOGV("Entering closeConvertSession");
    256     return mDrmManager->closeConvertSession(uniqueId, convertId);
    257 }
    258 
    259 status_t DrmManagerService::getAllSupportInfo(
    260             int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
    261     ALOGV("Entering getAllSupportInfo");
    262     return mDrmManager->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
    263 }
    264 
    265 DecryptHandle* DrmManagerService::openDecryptSession(
    266             int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
    267     ALOGV("Entering DrmManagerService::openDecryptSession");
    268     if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
    269         return mDrmManager->openDecryptSession(uniqueId, fd, offset, length, mime);
    270     }
    271 
    272     return NULL;
    273 }
    274 
    275 DecryptHandle* DrmManagerService::openDecryptSession(
    276             int uniqueId, const char* uri, const char* mime) {
    277     ALOGV("Entering DrmManagerService::openDecryptSession with uri");
    278     if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
    279         return mDrmManager->openDecryptSession(uniqueId, uri, mime);
    280     }
    281 
    282     return NULL;
    283 }
    284 
    285 DecryptHandle* DrmManagerService::openDecryptSession(
    286             int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
    287     ALOGV("Entering DrmManagerService::openDecryptSession for streaming");
    288     if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
    289         return mDrmManager->openDecryptSession(uniqueId, buf, mimeType);
    290     }
    291 
    292     return NULL;
    293 }
    294 
    295 status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
    296     ALOGV("Entering closeDecryptSession");
    297     if (!isProtectedCallAllowed(CLOSE_DECRYPT_SESSION)) {
    298         return DRM_ERROR_NO_PERMISSION;
    299     }
    300     return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
    301 }
    302 
    303 status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
    304             int decryptUnitId, const DrmBuffer* headerInfo) {
    305     ALOGV("Entering initializeDecryptUnit");
    306     if (!isProtectedCallAllowed(INITIALIZE_DECRYPT_UNIT)) {
    307         return DRM_ERROR_NO_PERMISSION;
    308     }
    309     return mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
    310 }
    311 
    312 status_t DrmManagerService::decrypt(
    313             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
    314             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
    315     ALOGV("Entering decrypt");
    316     if (!isProtectedCallAllowed(DECRYPT)) {
    317         return DRM_ERROR_NO_PERMISSION;
    318     }
    319     return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
    320 }
    321 
    322 status_t DrmManagerService::finalizeDecryptUnit(
    323             int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
    324     ALOGV("Entering finalizeDecryptUnit");
    325     if (!isProtectedCallAllowed(FINALIZE_DECRYPT_UNIT)) {
    326         return DRM_ERROR_NO_PERMISSION;
    327     }
    328     return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
    329 }
    330 
    331 ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
    332             void* buffer, ssize_t numBytes, off64_t offset) {
    333     ALOGV("Entering pread");
    334     if (!isProtectedCallAllowed(PREAD)) {
    335         return DRM_ERROR_NO_PERMISSION;
    336     }
    337     return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
    338 }
    339 
    340 status_t DrmManagerService::dump(int fd, const Vector<String16>& args)
    341 {
    342     const size_t SIZE = 256;
    343     char buffer[SIZE];
    344     String8 result;
    345     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
    346         snprintf(buffer, SIZE, "Permission Denial: "
    347                 "can't dump DrmManagerService from pid=%d, uid=%d\n",
    348                 IPCThreadState::self()->getCallingPid(),
    349                 IPCThreadState::self()->getCallingUid());
    350         result.append(buffer);
    351     } else {
    352 #if DRM_MEMORY_LEAK_TRACK
    353         bool dumpMem = false;
    354         for (size_t i = 0; i < args.size(); i++) {
    355             if (args[i] == String16("-m")) {
    356                 dumpMem = true;
    357             }
    358         }
    359         if (dumpMem) {
    360             result.append("\nDumping memory:\n");
    361             std::string s = dumpMemoryAddresses(100 /* limit */);
    362             result.append(s.c_str(), s.size());
    363         }
    364 #else
    365         (void)args;
    366 #endif
    367     }
    368     write(fd, result.string(), result.size());
    369     return NO_ERROR;
    370 }
    371 
    372