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

Commit 1adc92d3 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12508860 from d5090892 to 25Q1-release

Change-Id: I3bcb3d08fcf0ff23e17e92f2c3ba18c4fa24f00d
parents 5d4f2279 d5090892
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -171,3 +171,10 @@ flag {
    description: "Use the context-provided AttributionSource when checking for client permissions"
    bug: "190657833"
}

flag {
    namespace: "camera_platform"
    name: "check_full_attribution_source_chain"
    description: "Pass the full AttributionSource chain to PermissionChecker"
    bug: "190657833"
}
+5 −2
Original line number Diff line number Diff line
@@ -863,14 +863,17 @@ Track::Track(
    }

    populateUsageAndContentTypeFromStreamType();
    setPortMute(muted);

    mute_state_t newMuteState = mMuteState.load();
    newMuteState.muteFromPortVolume = muted;

    // Audio patch and call assistant volume are always max
    if (mAttr.usage == AUDIO_USAGE_CALL_ASSISTANT
            || mAttr.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
        mVolume = 1.0f;
        setPortMute(false);
        newMuteState.muteFromPortVolume = false;
    }
    mMuteState.store(newMuteState);

    mServerLatencySupported = checkServerLatencySupported(format, flags);
#ifdef TEE_SINK
+70 −52
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ namespace {
    const char* kProcessInfoServiceName = "processinfo";
    const char* kVirtualDeviceBackCameraId = "0";
    const char* kVirtualDeviceFrontCameraId = "1";
    const char* kUnknownPackageName = "<unknown>";

    int32_t getDeviceId(const android::CameraMetadata& cameraInfo) {
        if (!cameraInfo.exists(ANDROID_INFO_DEVICE_ID)) {
@@ -1605,14 +1606,18 @@ Status CameraService::initializeShimMetadata(int cameraId) {
    int callingPid = getCallingPid();
    logConnectionAttempt(callingPid, kServiceName, cameraIdStr, API_1);

    AttributionSourceState clientAttribution =
            buildAttributionSource(callingPid, uid, kServiceName, kDefaultDeviceId);

    if (!(ret = connectHelper<ICameraClient, Client>(
            sp<ICameraClient>{nullptr}, cameraIdStr, cameraId,
            kServiceName, /*systemNativeClient*/ false, {}, uid, callingPid,
            API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
                  sp<ICameraClient>{nullptr}, cameraIdStr, cameraId, clientAttribution,
                  /*systemNativeClient*/ false, API_1, /*shimUpdateOnly*/ true,
                  /*oomScoreOffset*/ 0,
                  /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
            /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
            /*forceSlowJpegMode*/false, cameraIdStr, /*isNonSystemNdk*/ false, /*out*/ tmp)
            ).isOk()) {
                  /*rotationOverride*/
                  hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
                  /*forceSlowJpegMode*/ false, cameraIdStr, /*isNonSystemNdk*/ false, /*out*/ tmp))
                 .isOk()) {
        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str());
    }
    return ret;
@@ -1681,14 +1686,11 @@ Status CameraService::getLegacyParametersLazy(int cameraId,
}

Status CameraService::validateConnectLocked(const std::string& cameraId,
        const std::string& clientName8, int clientUid, int clientPid) const {

                                            const AttributionSourceState& clientAttribution) const {
#ifdef __BRILLO__
    UNUSED(clientName8);
    UNUSED(clientUid);
    UNUSED(clientPid);
    UNUSED(clientAttribution);
#else
    Status allowed = validateClientPermissionsLocked(cameraId, clientName8, clientUid, clientPid);
    Status allowed = validateClientPermissionsLocked(cameraId, clientAttribution);
    if (!allowed.isOk()) {
        return allowed;
    }
@@ -1725,11 +1727,15 @@ Status CameraService::validateConnectLocked(const std::string& cameraId,
    return Status::ok();
}

Status CameraService::validateClientPermissionsLocked(const std::string& cameraId,
        const std::string& clientName, int clientUid, int clientPid) const {
Status CameraService::validateClientPermissionsLocked(
        const std::string& cameraId, const AttributionSourceState& clientAttribution) const {
    int callingPid = getCallingPid();
    int callingUid = getCallingUid();

    int clientPid = clientAttribution.pid;
    int clientUid = clientAttribution.uid;
    const std::string clientName = clientAttribution.packageName.value_or(kUnknownPackageName);

    if (shouldRejectSystemCameraConnection(cameraId)) {
        ALOGW("Attempting to connect to system-only camera id %s, connection rejected",
                cameraId.c_str());
@@ -1745,12 +1751,14 @@ Status CameraService::validateClientPermissionsLocked(const std::string& cameraI

    // Get the device id that owns this camera.
    auto [deviceId, _] = mVirtualDeviceCameraIdMapper.getDeviceIdAndMappedCameraIdPair(cameraId);
    AttributionSourceState clientAttributionWithDeviceId = clientAttribution;
    clientAttributionWithDeviceId.deviceId = deviceId;

    // 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).
    bool checkPermissionForCamera =
            hasPermissionsForCamera(cameraId, clientPid, clientUid, clientName, deviceId);
            hasPermissionsForCamera(cameraId, clientAttributionWithDeviceId);
    if (callingPid != getpid() &&
                (deviceKind != SystemCameraKind::SYSTEM_ONLY_CAMERA) && !checkPermissionForCamera) {
        ALOGE("Permission Denial: can't use the camera pid=%d, uid=%d", clientPid, clientUid);
@@ -2122,7 +2130,7 @@ Status CameraService::connect(
    ret = resolveAttributionSource(resolvedClientAttribution, __FUNCTION__, cameraIdStr);
    if (!ret.isOk()) {
        logRejected(cameraIdStr, getCallingPid(),
                    clientAttribution.packageName.value_or("<unknown>"),
                    clientAttribution.packageName.value_or(kUnknownPackageName),
                    toStdString(ret.toString8()));
        return ret;
    }
@@ -2134,15 +2142,15 @@ Status CameraService::connect(
    logConnectionAttempt(clientPid, clientPackageName, cameraIdStr, API_1);

    sp<Client> client = nullptr;
    ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
            clientPackageName, /*systemNativeClient*/ false, {},
            clientUid, clientPid, API_1,
            /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion,
            rotationOverride, forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*out*/client);
    ret = connectHelper<ICameraClient, Client>(
            cameraClient, cameraIdStr, api1CameraId, resolvedClientAttribution,
            /*systemNativeClient*/ false, API_1,
            /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion, rotationOverride,
            forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*out*/ client);

    if (!ret.isOk()) {
        logRejected(cameraIdStr, getCallingPid(),
                    clientAttribution.packageName.value_or("<unknown>"),
                    clientAttribution.packageName.value_or(kUnknownPackageName),
                    toStdString(ret.toString8()));
        return ret;
    }
@@ -2298,9 +2306,8 @@ Status CameraService::connectDevice(
    }

    ret = connectHelper<hardware::camera2::ICameraDeviceCallbacks, CameraDeviceClient>(
            cameraCb, cameraId, /*api1CameraId*/ -1, clientPackageName, systemNativeClient,
            resolvedClientAttribution.attributionTag, clientUid, clientPid, API_2,
            /*shimUpdateOnly*/ false, oomScoreOffset, targetSdkVersion, rotationOverride,
            cameraCb, cameraId, /*api1CameraId*/ -1, resolvedClientAttribution, systemNativeClient,
            API_2, /*shimUpdateOnly*/ false, oomScoreOffset, targetSdkVersion, rotationOverride,
            /*forceSlowJpegMode*/ false, unresolvedCameraId, isNonSystemNdk, /*out*/ client);

    if (!ret.isOk()) {
@@ -2375,11 +2382,13 @@ void CameraService::logConnectionAttempt(int clientPid, const std::string& clien

template <class CALLBACK, class CLIENT>
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
        int api1CameraId, const std::string& clientPackageName, bool systemNativeClient,
        const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
        apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
                                    int api1CameraId,
                                    const AttributionSourceState& clientAttribution,
                                    bool systemNativeClient, apiLevel effectiveApiLevel,
                                    bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
                                    int rotationOverride, bool forceSlowJpegMode,
        const std::string& originalCameraId, bool isNonSystemNdk, /*out*/sp<CLIENT>& device) {
                                    const std::string& originalCameraId, bool isNonSystemNdk,
                                    /*out*/ sp<CLIENT>& device) {
    binder::Status ret = binder::Status::ok();

    nsecs_t openTimeNs = systemTime();
@@ -2388,22 +2397,25 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str
    int facing = -1;
    int orientation = 0;

    const std::string clientPackageName =
            clientAttribution.packageName.value_or(kUnknownPackageName);

    {
        // Acquire mServiceLock and prevent other clients from connecting
        std::unique_ptr<AutoConditionLock> lock =
                AutoConditionLock::waitAndAcquire(mServiceLockWrapper, DEFAULT_CONNECT_TIMEOUT_NS);

        if (lock == nullptr) {
            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting)."
                    , clientPid);
            return STATUS_ERROR_FMT(ERROR_MAX_CAMERAS_IN_USE,
            ALOGE("CameraService::connect (PID %d) rejected (too many other clients connecting).",
                  clientAttribution.pid);
            return STATUS_ERROR_FMT(
                    ERROR_MAX_CAMERAS_IN_USE,
                    "Cannot open camera %s for \"%s\" (PID %d): Too many other clients connecting",
                    cameraId.c_str(), clientPackageName.c_str(), clientPid);
                    cameraId.c_str(), clientPackageName.c_str(), clientAttribution.pid);
        }

        // Enforce client permissions and do basic validity checks
        if (!(ret = validateConnectLocked(cameraId, clientPackageName,
                /*inout*/clientUid, /*inout*/clientPid)).isOk()) {
        if (!(ret = validateConnectLocked(cameraId, clientAttribution)).isOk()) {
            return ret;
        }

@@ -2420,9 +2432,12 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str

        sp<BasicClient> clientTmp = nullptr;
        std::shared_ptr<resource_policy::ClientDescriptor<std::string, sp<BasicClient>>> partial;
        if ((err = handleEvictionsLocked(cameraId, clientPid, effectiveApiLevel,
                IInterface::asBinder(cameraCb), clientPackageName, oomScoreOffset,
                systemNativeClient, /*out*/&clientTmp, /*out*/&partial)) != NO_ERROR) {
        if ((err = handleEvictionsLocked(
                     cameraId, clientAttribution.pid, effectiveApiLevel,
                     IInterface::asBinder(cameraCb),
                     clientAttribution.packageName.value_or(kUnknownPackageName), oomScoreOffset,
                     systemNativeClient, /*out*/ &clientTmp,
                     /*out*/ &partial)) != NO_ERROR) {
            switch (err) {
                case -ENODEV:
                    return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
@@ -2469,11 +2484,12 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str
        // Only use passed in clientPid to check permission. Use calling PID as the client PID
        // that's connected to camera service directly.
        if (!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
                clientFeatureId, cameraId, api1CameraId, facing,
                orientation, getCallingPid(), clientUid, getpid(),
                               clientAttribution.attributionTag, cameraId, api1CameraId, facing,
                               orientation, getCallingPid(), clientAttribution.uid, getpid(),
                               deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                               rotationOverride, forceSlowJpegMode, originalCameraId,
                /*out*/&tmp)).isOk()) {
                               /*out*/ &tmp))
                     .isOk()) {
            return ret;
        }
        client = static_cast<CLIENT*>(tmp.get());
@@ -2575,7 +2591,8 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str
            } else {
                client->setRotateAndCropOverride(
                        mCameraServiceProxyWrapper->getRotateAndCropOverride(
                        clientPackageName, facing, multiuser_get_user_id(clientUid)));
                                clientPackageName, facing,
                                multiuser_get_user_id(clientAttribution.uid)));
            }
        }

@@ -2600,8 +2617,9 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str
        bool isCameraPrivacyEnabled;
        if (flags::camera_privacy_allowlist()) {
            // Set camera muting behavior.
            isCameraPrivacyEnabled = this->isCameraPrivacyEnabled(
                    toString16(client->getPackageName()), cameraId, clientPid, clientUid);
            isCameraPrivacyEnabled =
                    this->isCameraPrivacyEnabled(toString16(client->getPackageName()), cameraId,
                                                 clientAttribution.pid, clientAttribution.uid);
        } else {
            isCameraPrivacyEnabled =
                    mSensorPrivacyPolicy->isCameraPrivacyEnabled();
+11 −13
Original line number Diff line number Diff line
@@ -927,12 +927,10 @@ private:
    void removeStates(const std::string& id);

    // Check if we can connect, before we acquire the service lock.
    // If clientPid/clientUid are USE_CALLING_PID/USE_CALLING_UID, they will be overwritten with
    // the calling pid/uid.
    binder::Status validateConnectLocked(const std::string& cameraId, const std::string& clientName,
            int clientUid, int clientPid) const;
    binder::Status validateClientPermissionsLocked(const std::string& cameraId,
            const std::string& clientName, int clientUid, int clientPid) const;
    binder::Status validateConnectLocked(const std::string& cameraId,
                                         const AttributionSourceState& clientAttribution) const;
    binder::Status validateClientPermissionsLocked(
            const std::string& cameraId, const AttributionSourceState& clientAttribution) const;

    void logConnectionAttempt(int clientPid, const std::string& clientPackageName,
        const std::string& cameraId, apiLevel effectiveApiLevel) const;
@@ -976,9 +974,9 @@ private:
    // Single implementation shared between the various connect calls
    template <class CALLBACK, class CLIENT>
    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
            int api1CameraId, const std::string& clientPackageName, bool systemNativeClient,
            const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
            apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
                                 int api1CameraId, const AttributionSourceState& clientAttribution,
                                 bool systemNativeClient, apiLevel effectiveApiLevel,
                                 bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
                                 int rotationOverride, bool forceSlowJpegMode,
                                 const std::string& originalCameraId, bool isNonSystemNdk,
                                 /*out*/ sp<CLIENT>& device);
+38 −4
Original line number Diff line number Diff line
@@ -32,7 +32,32 @@
#include <hwbinder/IPCThreadState.h>

namespace {

using android::content::AttributionSourceState;

static const std::string kPermissionServiceName = "permission";

static std::string getAttributionString(const AttributionSourceState& attributionSource) {
    std::ostringstream ret;
    const AttributionSourceState* current = &attributionSource;
    while (current != nullptr) {
        if (current != &attributionSource) {
            ret << ", ";
        }

        ret << "[uid " << current->uid << ", pid " << current->pid;
        ret << ", packageName \"" << current->packageName.value_or("<unknown>");
        ret << "\"]";

        if (!current->next.empty()) {
            current = &current->next[0];
        } else {
            current = nullptr;
        }
    }
    return ret.str();
}

} // namespace

namespace android {
@@ -111,13 +136,22 @@ bool AttributionAndPermissionUtils::checkPermissionForPreflight(
        const std::string& cameraId, const std::string& permission,
        const AttributionSourceState& attributionSource, const std::string& message,
        int32_t attributedOpCode) {
    if (checkAutomotivePrivilegedClient(cameraId, attributionSource)) {
    AttributionSourceState clientAttribution = attributionSource;
    if (!flags::check_full_attribution_source_chain() && !clientAttribution.next.empty()) {
        clientAttribution.next.clear();
    }

    if (checkAutomotivePrivilegedClient(cameraId, clientAttribution)) {
        return true;
    }

    return mPermissionChecker->checkPermissionForPreflight(
                   toString16(permission), attributionSource, toString16(message),
                   attributedOpCode) != PermissionChecker::PERMISSION_HARD_DENIED;
    PermissionChecker::PermissionResult result = mPermissionChecker->checkPermissionForPreflight(
            toString16(permission), clientAttribution, toString16(message), attributedOpCode);
    if (result == PermissionChecker::PERMISSION_HARD_DENIED) {
        ALOGE("%s: Permission denied for client attribution %s", __FUNCTION__,
              getAttributionString(clientAttribution).c_str());
    }
    return result != PermissionChecker::PERMISSION_HARD_DENIED;
}

// Can camera service trust the caller based on the calling UID?
Loading