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

Commit b7e2ef14 authored by Igor Murashkin's avatar Igor Murashkin Committed by Android (Google) Code Review
Browse files

Merge "ProCamera: Add security permission checks for disabling transmit LED" into jb-mr2-dev

parents a307beb6 03ac8505
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -203,6 +203,10 @@ status_t ProCamera2Client::submitRequest(camera_metadata_t* request,

    CameraMetadata metadata(request);

    if (!enforceRequestPermissions(metadata)) {
        return PERMISSION_DENIED;
    }

    if (streaming) {
        return mDevice->setStreamingRequest(metadata);
    } else {
@@ -388,4 +392,55 @@ void ProCamera2Client::onFrameAvailable(int32_t frameId,

}

bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {

    const int pid = IPCThreadState::self()->getCallingPid();
    const int selfPid = getpid();
    camera_metadata_entry_t entry;

    /**
     * Mixin default important security values
     * - android.led.transmit = defaulted ON
     */
    CameraMetadata staticInfo = mDevice->info();
    entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
    for(size_t i = 0; i < entry.count; ++i) {
        uint8_t led = entry.data.u8[i];

        switch(led) {
            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
                if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
                    metadata.update(ANDROID_LED_TRANSMIT,
                                    &transmitDefault, 1);
                }
                break;
            }
        }
    }

    // We can do anything!
    if (pid == selfPid) {
        return true;
    }

    /**
     * Permission check special fields in the request
     * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
     */
    entry = metadata.find(ANDROID_LED_TRANSMIT);
    if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
        String16 permissionString =
            String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
        if (!checkCallingPermission(permissionString)) {
            const int uid = IPCThreadState::self()->getCallingUid();
            ALOGE("Permission Denial: "
                  "can't disable transmit LED pid=%d, uid=%d", pid, uid);
            return false;
        }
    }

    return true;
}

} // namespace android
+1 −0
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ private:
    static const int32_t FRAME_PROCESSOR_LISTENER_MAX_ID = 0x7fffffffL;

    /** Utility members */
    bool enforceRequestPermissions(CameraMetadata& metadata);

    // Whether or not we have an exclusive lock on the device
    // - if no we can't modify the request queue.
+26 −0
Original line number Diff line number Diff line
@@ -1588,6 +1588,32 @@ status_t Parameters::updateRequest(CameraMetadata *request) const {
    ATRACE_CALL();
    status_t res;

    /**
     * Mixin default important security values
     * - android.led.transmit = defaulted ON
     */
    camera_metadata_ro_entry_t entry = staticInfo(ANDROID_LED_AVAILABLE_LEDS,
                                                  /*minimumCount*/0);
    for(size_t i = 0; i < entry.count; ++i) {
        uint8_t led = entry.data.u8[i];

        switch(led) {
            // Transmit LED is unconditionally on when using
            // the android.hardware.Camera API
            case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
                uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
                res = request->update(ANDROID_LED_TRANSMIT,
                                      &transmitDefault, 1);
                if (res != OK) return res;
                break;
            }
        }
    }

    /**
     * Construct metadata from parameters
     */

    uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL;
    res = request->update(ANDROID_REQUEST_METADATA_MODE,
            &metadataMode, 1);