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 --- camera/Camera.cpp | 9 +- camera/CameraBase.cpp | 4 +- camera/ICameraService.cpp | 24 ++--- include/camera/Camera.h | 4 +- include/camera/ICameraService.h | 6 +- services/camera/libcameraservice/CameraService.cpp | 120 +++++++++++++-------- services/camera/libcameraservice/CameraService.h | 22 ++-- .../libcameraservice/common/Camera2ClientBase.cpp | 2 +- 8 files changed, 112 insertions(+), 79 deletions(-) diff --git a/camera/Camera.cpp b/camera/Camera.cpp index 3a9fb4c..84e0d1c 100644 --- a/camera/Camera.cpp +++ b/camera/Camera.cpp @@ -71,14 +71,13 @@ Camera::~Camera() // deadlock if we call any method of ICamera here. } -sp Camera::connect(int cameraId, const String16& clientPackageName, - int clientUid) +sp Camera::connect(int cameraId, const String16& opPackageName, int clientUid) { - return CameraBaseT::connect(cameraId, clientPackageName, clientUid); + return CameraBaseT::connect(cameraId, opPackageName, clientUid); } status_t Camera::connectLegacy(int cameraId, int halVersion, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, sp& camera) { @@ -89,7 +88,7 @@ status_t Camera::connectLegacy(int cameraId, int halVersion, const sp& cs = CameraBaseT::getCameraService(); if (cs != 0) { - status = cs.get()->connectLegacy(cl, cameraId, halVersion, clientPackageName, + status = cs.get()->connectLegacy(cl, cameraId, halVersion, opPackageName, clientUid, /*out*/c->mCamera); } if (status == OK && c->mCamera != 0) { diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp index 5d50aa8..0dc0276 100644 --- a/camera/CameraBase.cpp +++ b/camera/CameraBase.cpp @@ -91,7 +91,7 @@ const sp& CameraBase::getCameraService() template sp CameraBase::connect(int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid) { ALOGV("%s: connect", __FUNCTION__); @@ -102,7 +102,7 @@ sp CameraBase::connect(int cameraId, if (cs != 0) { TCamConnectService fnConnectService = TCamTraits::fnConnectService; - status = (cs.get()->*fnConnectService)(cl, cameraId, clientPackageName, clientUid, + status = (cs.get()->*fnConnectService)(cl, cameraId, opPackageName, clientUid, /*out*/ c->mCamera); } if (status == OK && c->mCamera != 0) { diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp index 51a775b..192e40d 100644 --- a/camera/ICameraService.cpp +++ b/camera/ICameraService.cpp @@ -164,7 +164,7 @@ public: // connect to camera service (android.hardware.Camera) virtual status_t connect(const sp& cameraClient, int cameraId, - const String16 &clientPackageName, int clientUid, + const String16& opPackageName, int clientUid, /*out*/ sp& device) { @@ -172,7 +172,7 @@ public: data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(cameraClient)); data.writeInt32(cameraId); - data.writeString16(clientPackageName); + data.writeString16(opPackageName); data.writeInt32(clientUid); remote()->transact(BnCameraService::CONNECT, data, &reply); @@ -187,7 +187,7 @@ public: // connect to camera service (android.hardware.Camera) virtual status_t connectLegacy(const sp& cameraClient, int cameraId, int halVersion, - const String16 &clientPackageName, int clientUid, + const String16& opPackageName, int clientUid, /*out*/sp& device) { Parcel data, reply; @@ -195,7 +195,7 @@ public: data.writeStrongBinder(IInterface::asBinder(cameraClient)); data.writeInt32(cameraId); data.writeInt32(halVersion); - data.writeString16(clientPackageName); + data.writeString16(opPackageName); data.writeInt32(clientUid); remote()->transact(BnCameraService::CONNECT_LEGACY, data, &reply); @@ -225,7 +225,7 @@ public: virtual status_t connectDevice( const sp& cameraCb, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) @@ -234,7 +234,7 @@ public: data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(IInterface::asBinder(cameraCb)); data.writeInt32(cameraId); - data.writeString16(clientPackageName); + data.writeString16(opPackageName); data.writeInt32(clientUid); remote()->transact(BnCameraService::CONNECT_DEVICE, data, &reply); @@ -374,11 +374,11 @@ status_t BnCameraService::onTransact( sp cameraClient = interface_cast(data.readStrongBinder()); int32_t cameraId = data.readInt32(); - const String16 clientName = data.readString16(); + const String16 opPackageName = data.readString16(); int32_t clientUid = data.readInt32(); sp camera; status_t status = connect(cameraClient, cameraId, - clientName, clientUid, /*out*/camera); + opPackageName, clientUid, /*out*/camera); reply->writeNoException(); reply->writeInt32(status); if (camera != NULL) { @@ -394,11 +394,11 @@ status_t BnCameraService::onTransact( sp cameraClient = interface_cast(data.readStrongBinder()); int32_t cameraId = data.readInt32(); - const String16 clientName = data.readString16(); + const String16 opPackageName = data.readString16(); int32_t clientUid = data.readInt32(); sp camera; status_t status = connectDevice(cameraClient, cameraId, - clientName, clientUid, /*out*/camera); + opPackageName, clientUid, /*out*/camera); reply->writeNoException(); reply->writeInt32(status); if (camera != NULL) { @@ -454,11 +454,11 @@ status_t BnCameraService::onTransact( interface_cast(data.readStrongBinder()); int32_t cameraId = data.readInt32(); int32_t halVersion = data.readInt32(); - const String16 clientName = data.readString16(); + const String16 opPackageName = data.readString16(); int32_t clientUid = data.readInt32(); sp camera; status_t status = connectLegacy(cameraClient, cameraId, halVersion, - clientName, clientUid, /*out*/camera); + opPackageName, clientUid, /*out*/camera); reply->writeNoException(); reply->writeInt32(status); if (camera != NULL) { diff --git a/include/camera/Camera.h b/include/camera/Camera.h index 2b60842..25d75f7 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -71,11 +71,11 @@ public: // construct a camera client from an existing remote static sp create(const sp& camera); static sp connect(int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid); static status_t connectLegacy(int cameraId, int halVersion, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, sp& camera); virtual ~Camera(); diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index cad275e..38bff3e 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -109,7 +109,7 @@ public: */ virtual status_t connect(const sp& cameraClient, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) = 0; @@ -117,7 +117,7 @@ public: virtual status_t connectDevice( const sp& cameraCb, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) = 0; @@ -141,7 +141,7 @@ public: */ virtual status_t connectLegacy(const sp& cameraClient, int cameraId, int halVersion, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device) = 0; 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" : diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index a8b4c4a..502fcfa 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -126,19 +126,19 @@ public: virtual status_t getCameraVendorTagDescriptor(/*out*/ sp& desc); virtual status_t connect(const sp& cameraClient, int cameraId, - const String16& clientPackageName, int clientUid, + const String16& opPackageName, int clientUid, /*out*/ sp& device); virtual status_t connectLegacy(const sp& cameraClient, int cameraId, - int halVersion, const String16& clientPackageName, int clientUid, + int halVersion, const String16& opPackageName, int clientUid, /*out*/ sp& device); virtual status_t connectDevice( const sp& cameraCb, int cameraId, - const String16& clientPackageName, + const String16& opPackageName, int clientUid, /*out*/ sp& device); @@ -223,7 +223,7 @@ public: protected: BasicClient(const sp& cameraService, const sp& remoteCallback, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, @@ -242,7 +242,7 @@ public: sp mCameraService; // immutable after constructor int mCameraId; // immutable after constructor int mCameraFacing; // immutable after constructor - const String16 mClientPackageName; + const String16 mOpPackageName; pid_t mClientPid; uid_t mClientUid; // immutable after constructor pid_t mServicePid; // immutable after constructor @@ -309,7 +309,7 @@ public: // Interface used by CameraService Client(const sp& cameraService, const sp& cameraClient, - const String16& clientPackageName, + const String16& opPackageName, int cameraId, int cameraFacing, int clientPid, @@ -480,7 +480,7 @@ private: // Single implementation shared between the various connect calls template status_t connectHelper(const sp& cameraCb, const String8& cameraId, int halVersion, - const String16& clientPackageName, int clientUid, apiLevel effectiveApiLevel, + const String16& opPackageName, int clientUid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp& device); @@ -713,6 +713,8 @@ private: int facing, int clientPid, uid_t clientUid, int servicePid, bool legacyMode, int halVersion, int deviceVersion, apiLevel effectiveApiLevel, /*out*/sp* client); + + status_t checkCameraAccess(const String16& opPackageName); }; template @@ -761,11 +763,11 @@ void CameraService::CameraState::updateStatus(ICameraServiceListener::Status sta template status_t CameraService::connectHelper(const sp& cameraCb, const String8& cameraId, - int halVersion, const String16& clientPackageName, int clientUid, + int halVersion, const String16& opPackageName, int clientUid, apiLevel effectiveApiLevel, bool legacyMode, bool shimUpdateOnly, /*out*/sp& device) { status_t ret = NO_ERROR; - String8 clientName8(clientPackageName); + String8 clientName8(opPackageName); int clientPid = getCallingPid(); ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and " @@ -836,7 +838,7 @@ status_t CameraService::connectHelper(const sp& cameraCb, const String int facing = -1; int deviceVersion = getDeviceVersion(id, /*out*/&facing); sp tmp = nullptr; - if((ret = makeClient(this, cameraCb, clientPackageName, cameraId, facing, clientPid, + if((ret = makeClient(this, cameraCb, opPackageName, cameraId, facing, clientPid, clientUid, getpid(), legacyMode, halVersion, deviceVersion, effectiveApiLevel, /*out*/&tmp)) != NO_ERROR) { return ret; diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp index ba0b264..9b2e143 100644 --- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp +++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp @@ -118,7 +118,7 @@ Camera2ClientBase::~Camera2ClientBase() { ALOGI("Closed Camera %d. Client was: %s (PID %d, UID %u)", TClientBase::mCameraId, - String8(TClientBase::mClientPackageName).string(), + String8(TClientBase::mOpPackageName).string(), mInitialClientPid, TClientBase::mClientUid); } -- cgit v1.1