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

Commit b109a108 authored by Charles Chen's avatar Charles Chen Committed by Android (Google) Code Review
Browse files

Merge "Switch CameraService permission checks to PermissionController"

parents bd6eb57a 02c13d01
Loading
Loading
Loading
Loading
+55 −14
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
#include <android/permission/PermissionChecker.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
@@ -691,11 +692,18 @@ void CameraService::onTorchStatusChangedLocked(const String8& cameraId,
    broadcastTorchModeStatus(cameraId, newStatus, systemCameraKind);
}

static bool hasPermissionsForSystemCamera(int callingPid, int callingUid,
        bool logPermissionFailure = false) {
    return checkPermission(sSystemCameraPermission, callingPid, callingUid,
            logPermissionFailure) &&
            checkPermission(sCameraPermission, callingPid, callingUid);
static bool hasPermissionsForSystemCamera(int callingPid, int callingUid) {
    permission::PermissionChecker permissionChecker;
    AttributionSourceState attributionSource{};
    attributionSource.pid = callingPid;
    attributionSource.uid = callingUid;
    bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
            sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
            sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
    return checkPermissionForSystemCamera && checkPermissionForCamera;
}

Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
@@ -774,8 +782,14 @@ std::string CameraService::cameraIdIntToStrLocked(int cameraIdInt) {
    const std::vector<std::string> *deviceIds = &mNormalDeviceIdsWithoutSystemCamera;
    auto callingPid = CameraThreadState::getCallingPid();
    auto callingUid = CameraThreadState::getCallingUid();
    if (checkPermission(sSystemCameraPermission, callingPid, callingUid,
            /*logPermissionFailure*/false) || getpid() == callingPid) {
    permission::PermissionChecker permissionChecker;
    AttributionSourceState attributionSource{};
    attributionSource.pid = callingPid;
    attributionSource.uid = callingUid;
    bool checkPermissionForSystemCamera = permissionChecker.checkPermissionForPreflight(
                sSystemCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
    if (checkPermissionForSystemCamera || getpid() == callingPid) {
        deviceIds = &mNormalDeviceIds;
    }
    if (cameraIdInt < 0 || cameraIdInt >= static_cast<int>(deviceIds->size())) {
@@ -846,9 +860,16 @@ Status CameraService::getCameraCharacteristics(const String16& cameraId,
    // If it's not calling from cameraserver, check the permission only if
    // android.permission.CAMERA is required. If android.permission.SYSTEM_CAMERA was needed,
    // it would've already been checked in shouldRejectSystemCameraConnection.
    permission::PermissionChecker permissionChecker;
    AttributionSourceState attributionSource{};
    attributionSource.pid = callingPid;
    attributionSource.uid = callingUid;
    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
    if ((callingPid != getpid()) &&
            (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
            !checkPermission(sCameraPermission, callingPid, callingUid)) {
            !checkPermissionForCamera) {
        res = cameraInfo->removePermissionEntries(
                mCameraProviderManager->getProviderTagIdLocked(String8(cameraId).string()),
                &tagsRemoved);
@@ -1282,6 +1303,9 @@ Status CameraService::validateConnectLocked(const String8& cameraId,
Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
        const String8& clientName8, int& clientUid, int& clientPid,
        /*out*/int& originalClientPid) const {
    permission::PermissionChecker permissionChecker;
    AttributionSourceState attributionSource{};

    int callingPid = CameraThreadState::getCallingPid();
    int callingUid = CameraThreadState::getCallingUid();

@@ -1328,9 +1352,14 @@ Status CameraService::validateClientPermissionsLocked(const String8& cameraId,
    // If it's not calling from cameraserver, check the permission if the
    // device isn't a system only camera (shouldRejectSystemCameraConnection already checks for
    // android.permission.SYSTEM_CAMERA for system only camera devices).
    attributionSource.pid = clientPid;
    attributionSource.uid = clientUid;
    attributionSource.packageName = clientName8;
    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
            sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
            != permission::PermissionChecker::PERMISSION_HARD_DENIED;
    if (callingPid != getpid() &&
                (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) &&
                !checkPermission(sCameraPermission, clientPid, clientUid)) {
                (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
        ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
        return STATUS_ERROR_FMT(ERROR_PERMISSION_DENIED,
                "Caller \"%s\" (PID %d, UID %d) cannot open camera \"%s\" without camera permission",
@@ -1719,7 +1748,7 @@ bool CameraService::shouldRejectSystemCameraConnection(const String8& cameraId)
    //     characteristics) even if clients don't have android.permission.CAMERA. We do not want the
    //     same behavior for system camera devices.
    if (!systemClient && systemCameraKind == SystemCameraKind::SYSTEM_ONLY_CAMERA &&
            !hasPermissionsForSystemCamera(cPid, cUid, /*logPermissionFailure*/true)) {
            !hasPermissionsForSystemCamera(cPid, cUid)) {
        ALOGW("Rejecting access to system only camera %s, inadequete permissions",
                cameraId.c_str());
        return true;
@@ -2673,7 +2702,14 @@ Status CameraService::isConcurrentSessionConfigurationSupported(
    // Check for camera permissions
    int callingPid = CameraThreadState::getCallingPid();
    int callingUid = CameraThreadState::getCallingUid();
    if ((callingPid != getpid()) && !checkPermission(sCameraPermission, callingPid, callingUid)) {
    permission::PermissionChecker permissionChecker;
    AttributionSourceState attributionSource{};
    attributionSource.pid = callingPid;
    attributionSource.uid = callingUid;
    bool checkPermissionForCamera = permissionChecker.checkPermissionForPreflight(
                sCameraPermission, attributionSource, String16(), AppOpsManager::OP_NONE)
                != permission::PermissionChecker::PERMISSION_HARD_DENIED;
    if ((callingPid != getpid()) && !checkPermissionForCamera) {
        ALOGE("%s: pid %d doesn't have camera permissions", __FUNCTION__, callingPid);
        return STATUS_ERROR(ERROR_PERMISSION_DENIED,
                "android.permission.CAMERA needed to call"
@@ -2720,8 +2756,13 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen

    auto clientUid = CameraThreadState::getCallingUid();
    auto clientPid = CameraThreadState::getCallingPid();
    bool openCloseCallbackAllowed = checkPermission(sCameraOpenCloseListenerPermission,
            clientPid, clientUid, /*logPermissionFailure*/false);
    permission::PermissionChecker permissionChecker;
    AttributionSourceState attributionSource{};
    attributionSource.uid = clientUid;
    attributionSource.pid = clientPid;
    bool openCloseCallbackAllowed = permissionChecker.checkPermissionForPreflight(
            sCameraOpenCloseListenerPermission, attributionSource, String16(),
            AppOpsManager::OP_NONE) != permission::PermissionChecker::PERMISSION_HARD_DENIED;

    Mutex::Autolock lock(mServiceLock);