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

Commit 7d2b9232 authored by Austin Borger's avatar Austin Borger
Browse files

Resolve client package name and log connect early.

As a part of the effort to integrate AttributionSource into the camera
server and to avoid flag checks in too many locations, this change
approaches clustering resolution of the client's identity in a single
location. This will lead to a single flag check in a future CL whether
to rely on the AttributionSourceState data or to check for
USE_CALLING_*.

Flag: EXEMPT Strict mechanical refactor
Bug: 190657833
Test: atest CtsCameraTestCases, Camera1 + Camera2 apps
Change-Id: Ia07451da7926db7aff476f35974cbe31781045ad
parent 33f27be0
Loading
Loading
Loading
Loading
+54 −33
Original line number Original line Diff line number Diff line
@@ -1611,13 +1611,16 @@ Status CameraService::initializeShimMetadata(int cameraId) {
    std::string cameraIdStr = std::to_string(cameraId);
    std::string cameraIdStr = std::to_string(cameraId);
    Status ret = Status::ok();
    Status ret = Status::ok();
    sp<Client> tmp = nullptr;
    sp<Client> tmp = nullptr;

    logConnectionAttempt(getCallingPid(), kServiceName, cameraIdStr, API_1);

    if (!(ret = connectHelper<ICameraClient,Client>(
    if (!(ret = connectHelper<ICameraClient,Client>(
            sp<ICameraClient>{nullptr}, cameraIdStr, cameraId,
            sp<ICameraClient>{nullptr}, cameraIdStr, cameraId,
            kServiceName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
            kServiceName, /*systemNativeClient*/ false, {}, uid, USE_CALLING_PID,
            API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
            API_1, /*shimUpdateOnly*/ true, /*oomScoreOffset*/ 0,
            /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
            /*targetSdkVersion*/ __ANDROID_API_FUTURE__,
            /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
            /*rotationOverride*/hardware::ICameraService::ROTATION_OVERRIDE_OVERRIDE_TO_PORTRAIT,
            /*forceSlowJpegMode*/false, cameraIdStr, /*out*/ tmp)
            /*forceSlowJpegMode*/false, cameraIdStr, /*isNonSystemNdk*/ false, /*out*/ tmp)
            ).isOk()) {
            ).isOk()) {
        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str());
        ALOGE("%s: Error initializing shim metadata: %s", __FUNCTION__, ret.toString8().c_str());
    }
    }
@@ -2147,12 +2150,18 @@ Status CameraService::connect(
        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
        return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.c_str());
    }
    }


    std::string clientPackageNameMaybe = clientAttribution.packageName.value_or("");
    bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
    std::string clientPackageName = resolvePackageName(clientAttribution.uid,
            clientPackageNameMaybe);
    logConnectionAttempt(clientAttribution.pid, clientPackageName, cameraIdStr, API_1);

    sp<Client> client = nullptr;
    sp<Client> client = nullptr;
    ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
    ret = connectHelper<ICameraClient,Client>(cameraClient, cameraIdStr, api1CameraId,
            clientAttribution.packageName.value_or(""), /*systemNativeClient*/ false, {},
            clientPackageName, /*systemNativeClient*/ false, {},
            clientAttribution.uid, clientAttribution.pid, API_1,
            clientAttribution.uid, clientAttribution.pid, API_1,
            /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion,
            /*shimUpdateOnly*/ false, /*oomScoreOffset*/ 0, targetSdkVersion,
            rotationOverride, forceSlowJpegMode, cameraIdStr, /*out*/client);
            rotationOverride, forceSlowJpegMode, cameraIdStr, isNonSystemNdk, /*out*/client);


    if (!ret.isOk()) {
    if (!ret.isOk()) {
        logRejected(cameraIdStr, getCallingPid(), clientAttribution.packageName.value_or(""),
        logRejected(cameraIdStr, getCallingPid(), clientAttribution.packageName.value_or(""),
@@ -2241,13 +2250,13 @@ Status CameraService::connectDevice(
    RunThreadWithRealtimePriority priorityBump;
    RunThreadWithRealtimePriority priorityBump;
    Status ret = Status::ok();
    Status ret = Status::ok();
    sp<CameraDeviceClient> client = nullptr;
    sp<CameraDeviceClient> client = nullptr;
    std::string clientPackageNameAdj = clientAttribution.packageName.value_or("");
    std::string clientPackageNameMaybe = clientAttribution.packageName.value_or("");
    int callingPid = getCallingPid();
    int callingPid = getCallingPid();
    int callingUid = getCallingUid();
    int callingUid = getCallingUid();
    bool systemNativeClient = false;
    bool systemNativeClient = false;
    if (callerHasSystemUid() && (clientPackageNameAdj.size() == 0)) {
    if (callerHasSystemUid() && (clientPackageNameMaybe.size() == 0)) {
        std::string systemClient = fmt::sprintf("client.pid<%d>", callingPid);
        std::string systemClient = fmt::sprintf("client.pid<%d>", callingPid);
        clientPackageNameAdj = systemClient;
        clientPackageNameMaybe = systemClient;
        systemNativeClient = true;
        systemNativeClient = true;
    }
    }


@@ -2261,10 +2270,15 @@ Status CameraService::connectDevice(
    }
    }
    std::string cameraId = cameraIdOptional.value();
    std::string cameraId = cameraIdOptional.value();


    bool isNonSystemNdk = clientPackageNameMaybe.size() == 0;
    std::string clientPackageName = resolvePackageName(clientAttribution.uid,
            clientPackageNameMaybe);
    logConnectionAttempt(clientAttribution.pid, clientPackageName, cameraId, API_2);

    if (oomScoreOffset < 0) {
    if (oomScoreOffset < 0) {
        std::string msg =
        std::string msg =
                fmt::sprintf("Cannot increase the priority of a client %s pid %d for "
                fmt::sprintf("Cannot increase the priority of a client %s pid %d for "
                        "camera id %s", clientPackageNameAdj.c_str(), callingPid,
                        "camera id %s", clientPackageName.c_str(), callingPid,
                        cameraId.c_str());
                        cameraId.c_str());
        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
        return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.c_str());
@@ -2291,19 +2305,19 @@ Status CameraService::connectDevice(
            && !isTrustedCallingUid(callingUid)) {
            && !isTrustedCallingUid(callingUid)) {
        std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for "
        std::string msg = fmt::sprintf("Cannot change the priority of a client %s pid %d for "
                        "camera id %s without SYSTEM_CAMERA permissions",
                        "camera id %s without SYSTEM_CAMERA permissions",
                        clientPackageNameAdj.c_str(), callingPid, cameraId.c_str());
                        clientPackageName.c_str(), callingPid, cameraId.c_str());
        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
        ALOGE("%s: %s", __FUNCTION__, msg.c_str());
        return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
        return STATUS_ERROR(ERROR_PERMISSION_DENIED, msg.c_str());
    }
    }


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


    if (!ret.isOk()) {
    if (!ret.isOk()) {
        logRejected(cameraId, callingPid, clientPackageNameAdj, toStdString(ret.toString8()));
        logRejected(cameraId, callingPid, clientPackageName, toStdString(ret.toString8()));
        return ret;
        return ret;
    }
    }


@@ -2363,7 +2377,7 @@ bool CameraService::isCameraPrivacyEnabled(const String16& packageName, const st
    return false;
    return false;
}
}


std::string CameraService::getPackageNameFromUid(int clientUid) {
std::string CameraService::getPackageNameFromUid(int clientUid) const {
    std::string packageName("");
    std::string packageName("");


    sp<IPermissionController> permCtrl;
    sp<IPermissionController> permCtrl;
@@ -2408,37 +2422,44 @@ std::string CameraService::getPackageNameFromUid(int clientUid) {
    return packageName;
    return packageName;
}
}


template<class CALLBACK, class CLIENT>
void CameraService::logConnectionAttempt(int clientPid, const std::string& clientPackageName,
Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
        const std::string& cameraId, apiLevel effectiveApiLevel) const {
        int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient,
    int packagePid = (clientPid == USE_CALLING_PID) ?
        const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
        getCallingPid() : clientPid;
        apiLevel effectiveApiLevel, bool shimUpdateOnly, int oomScoreOffset, int targetSdkVersion,
    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
        int rotationOverride, bool forceSlowJpegMode,
            "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(),
        const std::string& originalCameraId, /*out*/sp<CLIENT>& device) {
            static_cast<int>(effectiveApiLevel));
    binder::Status ret = binder::Status::ok();
}


    bool isNonSystemNdk = false;
std::string CameraService::resolvePackageName(int clientUid,
    std::string clientPackageName;
        const std::string& clientPackageNameMaybe) const {
    if (clientPackageNameMaybe.size() <= 0) {
        int packageUid = (clientUid == USE_CALLING_UID) ?
        int packageUid = (clientUid == USE_CALLING_UID) ?
                getCallingUid() : clientUid;
                getCallingUid() : clientUid;
    int callingPid = getCallingPid();
    if (clientPackageNameMaybe.size() <= 0) {
        // NDK calls don't come with package names, but we need one for various cases.
        // NDK calls don't come with package names, but we need one for various cases.
        // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
        // Generally, there's a 1:1 mapping between UID and package name, but shared UIDs
        // do exist. For all authentication cases, all packages under the same UID get the
        // do exist. For all authentication cases, all packages under the same UID get the
        // same permissions, so picking any associated package name is sufficient. For some
        // same permissions, so picking any associated package name is sufficient. For some
        // other cases, this may give inaccurate names for clients in logs.
        // other cases, this may give inaccurate names for clients in logs.
        isNonSystemNdk = true;
        return getPackageNameFromUid(packageUid);
        clientPackageName = getPackageNameFromUid(packageUid);
    } else {
    } else {
        clientPackageName = clientPackageNameMaybe;
        return clientPackageNameMaybe;
    }
}
}


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 rotationOverride, bool forceSlowJpegMode,
        const std::string& originalCameraId, bool isNonSystemNdk, /*out*/sp<CLIENT>& device) {
    binder::Status ret = binder::Status::ok();

    int packageUid = (clientUid == USE_CALLING_UID) ?
            getCallingUid() : clientUid;
    int packagePid = (clientPid == USE_CALLING_PID) ?
    int packagePid = (clientPid == USE_CALLING_PID) ?
        callingPid : clientPid;
            getCallingPid() : clientPid;
    ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) and "
            "Camera API version %d", packagePid, clientPackageName.c_str(), cameraId.c_str(),
            static_cast<int>(effectiveApiLevel));


    nsecs_t openTimeNs = systemTime();
    nsecs_t openTimeNs = systemTime();


@@ -2528,7 +2549,7 @@ Status CameraService::connectHelper(const sp<CALLBACK>& cameraCb, const std::str
        // that's connected to camera service directly.
        // that's connected to camera service directly.
        if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
        if(!(ret = makeClient(this, cameraCb, clientPackageName, systemNativeClient,
                clientFeatureId, cameraId, api1CameraId, facing,
                clientFeatureId, cameraId, api1CameraId, facing,
                orientation, callingPid, clientUid, getpid(),
                orientation, getCallingPid(), clientUid, getpid(),
                deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                deviceVersionAndTransport, effectiveApiLevel, overrideForPerfClass,
                rotationOverride, forceSlowJpegMode, originalCameraId,
                rotationOverride, forceSlowJpegMode, originalCameraId,
                /*out*/&tmp)).isOk()) {
                /*out*/&tmp)).isOk()) {
+8 −3
Original line number Original line Diff line number Diff line
@@ -954,6 +954,11 @@ private:
    binder::Status validateClientPermissionsLocked(const std::string& cameraId,
    binder::Status validateClientPermissionsLocked(const std::string& cameraId,
            const std::string& clientName, /*inout*/int& clientUid, /*inout*/int& clientPid) const;
            const std::string& clientName, /*inout*/int& clientUid, /*inout*/int& clientPid) const;


    // If clientPackageNameMaybe is empty, attempts to resolve the package name.
    std::string resolvePackageName(int clientUid, const std::string& clientPackageNameMaybe) const;
    void logConnectionAttempt(int clientPid, const std::string& clientPackageName,
        const std::string& cameraId, apiLevel effectiveApiLevel) const;

    bool isCameraPrivacyEnabled(const String16& packageName,const std::string& cameraId,
    bool isCameraPrivacyEnabled(const String16& packageName,const std::string& cameraId,
           int clientPid, int ClientUid);
           int clientPid, int ClientUid);


@@ -997,16 +1002,16 @@ private:
    // as for legacy apps we will toggle the app op for all packages in the UID.
    // as for legacy apps we will toggle the app op for all packages in the UID.
    // The caveat is that the operation may be attributed to the wrong package and
    // The caveat is that the operation may be attributed to the wrong package and
    // stats based on app ops may be slightly off.
    // stats based on app ops may be slightly off.
    std::string getPackageNameFromUid(int clientUid);
    std::string getPackageNameFromUid(int clientUid) const;


    // Single implementation shared between the various connect calls
    // Single implementation shared between the various connect calls
    template<class CALLBACK, class CLIENT>
    template<class CALLBACK, class CLIENT>
    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
    binder::Status connectHelper(const sp<CALLBACK>& cameraCb, const std::string& cameraId,
            int api1CameraId, const std::string& clientPackageNameMaybe, bool systemNativeClient,
            int api1CameraId, const std::string& clientPackageName, bool systemNativeClient,
            const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
            const std::optional<std::string>& clientFeatureId, int clientUid, int clientPid,
            apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
            apiLevel effectiveApiLevel, bool shimUpdateOnly, int scoreOffset, int targetSdkVersion,
            int rotationOverride, bool forceSlowJpegMode,
            int rotationOverride, bool forceSlowJpegMode,
            const std::string& originalCameraId,
            const std::string& originalCameraId, bool isNonSystemNdk,
            /*out*/sp<CLIENT>& device);
            /*out*/sp<CLIENT>& device);


    // Lock guarding camera service state
    // Lock guarding camera service state