From 32fa6d0e65dbf956e253a1006e9419dce2fe75c9 Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Fri, 1 May 2015 20:47:20 -0700 Subject: Add camera app op - camera Change-Id: I26570cc0a23fdea740b416a26838d40cac296c85 --- services/camera/libcameraservice/CameraService.cpp | 120 +++++++++++++-------- 1 file changed, 76 insertions(+), 44 deletions(-) (limited to 'services/camera/libcameraservice/CameraService.cpp') diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index e28464d..3f80faf 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -1057,19 +1057,24 @@ status_t CameraService::handleEvictionsLocked(const String8& cameraId, int clien status_t CameraService::connect( const sp& cameraClient, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) { + const status_t result = checkCameraAccess(opPackageName); + if (result != NO_ERROR) { + return result; + } + status_t ret = NO_ERROR; String8 id = String8::format("%d", cameraId); sp client = nullptr; ret = connectHelper(cameraClient, id, CAMERA_HAL_API_VERSION_UNSPECIFIED, - clientPackageName, clientUid, API_1, false, false, /*out*/client); + opPackageName, clientUid, API_1, false, false, /*out*/client); if(ret != NO_ERROR) { - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8::format("%s (%d)", strerror(-ret), ret)); return ret; } @@ -1081,11 +1086,16 @@ status_t CameraService::connect( status_t CameraService::connectLegacy( const sp& cameraClient, int cameraId, int halVersion, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) { + const status_t result = checkCameraAccess(opPackageName); + if (result != NO_ERROR) { + return result; + } + String8 id = String8::format("%d", cameraId); int apiVersion = mModule->getModuleApiVersion(); if (halVersion != CAMERA_HAL_API_VERSION_UNSPECIFIED && @@ -1098,18 +1108,18 @@ status_t CameraService::connectLegacy( */ ALOGE("%s: camera HAL module version %x doesn't support connecting to legacy HAL devices!", __FUNCTION__, apiVersion); - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8("HAL module version doesn't support legacy HAL connections")); return INVALID_OPERATION; } status_t ret = NO_ERROR; sp client = nullptr; - ret = connectHelper(cameraClient, id, halVersion, clientPackageName, + ret = connectHelper(cameraClient, id, halVersion, opPackageName, clientUid, API_1, true, false, /*out*/client); if(ret != NO_ERROR) { - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8::format("%s (%d)", strerror(-ret), ret)); return ret; } @@ -1121,20 +1131,25 @@ status_t CameraService::connectLegacy( status_t CameraService::connectDevice( const sp& cameraCb, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) { + const status_t result = checkCameraAccess(opPackageName); + if (result != NO_ERROR) { + return result; + } + status_t ret = NO_ERROR; String8 id = String8::format("%d", cameraId); sp client = nullptr; ret = connectHelper(cameraCb, id, - CAMERA_HAL_API_VERSION_UNSPECIFIED, clientPackageName, clientUid, API_2, false, false, + CAMERA_HAL_API_VERSION_UNSPECIFIED, opPackageName, clientUid, API_2, false, false, /*out*/client); if(ret != NO_ERROR) { - logRejected(id, getCallingPid(), String8(clientPackageName), + logRejected(id, getCallingPid(), String8(opPackageName), String8::format("%s (%d)", strerror(-ret), ret)); return ret; } @@ -1529,24 +1544,24 @@ void CameraService::logEvent(const char* event) { } void CameraService::logDisconnected(const char* cameraId, int clientPid, - const char* clientPackage) { + const char* opPackageName) { // Log the clients evicted logEvent(String8::format("DISCONNECT device %s client for package %s (PID %d)", cameraId, - clientPackage, clientPid)); + opPackageName, clientPid)); } void CameraService::logConnected(const char* cameraId, int clientPid, - const char* clientPackage) { + const char* opPackageName) { // Log the clients evicted logEvent(String8::format("CONNECT device %s client for package %s (PID %d)", cameraId, - clientPackage, clientPid)); + opPackageName, clientPid)); } void CameraService::logRejected(const char* cameraId, int clientPid, - const char* clientPackage, const char* reason) { + const char* opPackageName, const char* reason) { // Log the client rejected logEvent(String8::format("REJECT device %s client for package %s (PID %d), reason: (%s)", - cameraId, clientPackage, clientPid, reason)); + cameraId, opPackageName, clientPid, reason)); } void CameraService::logUserSwitch(int oldUserId, int newUserId) { @@ -1583,21 +1598,6 @@ status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* re // Permission checks switch (code) { - case BnCameraService::CONNECT: - case BnCameraService::CONNECT_DEVICE: - case BnCameraService::CONNECT_LEGACY: { - if (pid != selfPid) { - // we're called from a different process, do the real check - if (!checkCallingPermission( - String16("android.permission.CAMERA"))) { - const int uid = getCallingUid(); - ALOGE("Permission Denial: " - "can't use the camera pid=%d, uid=%d", pid, uid); - return PERMISSION_DENIED; - } - } - break; - } case BnCameraService::NOTIFY_SYSTEM_EVENT: { if (pid != selfPid) { // Ensure we're being called by system_server, or similar process with @@ -1617,6 +1617,38 @@ status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* re return BnCameraService::onTransact(code, data, reply, flags); } +status_t CameraService::checkCameraAccess(const String16& opPackageName) { + const int pid = getCallingPid(); + + if (pid == getpid()) { + return NO_ERROR; + } + + const int uid = getCallingUid(); + + if (!checkCallingPermission(String16("android.permission.CAMERA"))) { + ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; + } + + AppOpsManager appOps; + const int32_t result = appOps.noteOp(AppOpsManager::OP_CAMERA, uid, opPackageName); + + switch (result) { + case AppOpsManager::MODE_ERRORED: { + ALOGE("App op OP_CAMERA errored: can't use the camera pid=%d, uid=%d", pid, uid); + return PERMISSION_DENIED; + } break; + + case AppOpsManager::MODE_IGNORED: { + ALOGE("App op OP_CAMERA ignored: can't use the camera pid=%d, uid=%d", pid, uid); + return INVALID_OPERATION; + } break; + } + + return NO_ERROR; +} + // We share the media players for shutter and recording sound for all clients. // A reference count is kept to determine when we will actually release the // media players. @@ -1669,13 +1701,13 @@ void CameraService::playSound(sound_kind kind) { CameraService::Client::Client(const sp& cameraService, const sp& cameraClient, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid) : CameraService::BasicClient(cameraService, IInterface::asBinder(cameraClient), - clientPackageName, + opPackageName, cameraId, cameraFacing, clientPid, clientUid, servicePid) @@ -1702,11 +1734,11 @@ CameraService::Client::~Client() { CameraService::BasicClient::BasicClient(const sp& cameraService, const sp& remoteCallback, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, uid_t clientUid, int servicePid): - mClientPackageName(clientPackageName), mDisconnected(false) + mOpPackageName(opPackageName), mDisconnected(false) { mCameraService = cameraService; mRemoteBinder = remoteCallback; @@ -1734,7 +1766,7 @@ void CameraService::BasicClient::disconnect() { mCameraService->removeByClient(this); mCameraService->logDisconnected(String8::format("%d", mCameraId), mClientPid, - String8(mClientPackageName)); + String8(mOpPackageName)); sp remote = getRemote(); if (remote != nullptr) { @@ -1749,7 +1781,7 @@ void CameraService::BasicClient::disconnect() { } String16 CameraService::BasicClient::getPackageName() const { - return mClientPackageName; + return mOpPackageName; } @@ -1769,17 +1801,17 @@ status_t CameraService::BasicClient::startCameraOps() { { ALOGV("%s: Start camera ops, package name = %s, client UID = %d", - __FUNCTION__, String8(mClientPackageName).string(), mClientUid); + __FUNCTION__, String8(mOpPackageName).string(), mClientUid); } mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA, - mClientPackageName, mOpsCallback); + mOpPackageName, mOpsCallback); res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA, - mClientUid, mClientPackageName); + mClientUid, mOpPackageName); if (res != AppOpsManager::MODE_ALLOWED) { ALOGI("Camera %d: Access for \"%s\" has been revoked", - mCameraId, String8(mClientPackageName).string()); + mCameraId, String8(mOpPackageName).string()); return PERMISSION_DENIED; } @@ -1797,7 +1829,7 @@ status_t CameraService::BasicClient::finishCameraOps() { if (mOpsActive) { // Notify app ops that the camera is available again mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid, - mClientPackageName); + mOpPackageName); mOpsActive = false; auto rejected = {ICameraServiceListener::STATUS_NOT_PRESENT, @@ -1822,7 +1854,7 @@ status_t CameraService::BasicClient::finishCameraOps() { void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) { String8 name(packageName); - String8 myName(mClientPackageName); + String8 myName(mOpPackageName); if (op != AppOpsManager::OP_CAMERA) { ALOGW("Unexpected app ops notification received: %d", op); @@ -1831,7 +1863,7 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16& packageNa int32_t res; res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA, - mClientUid, mClientPackageName); + mClientUid, mOpPackageName); ALOGV("checkOp returns: %d, %s ", res, res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" : res == AppOpsManager::MODE_IGNORED ? "IGNORED" : -- cgit v1.1