From: Igor Murashkin Date: Tue, 23 Apr 2013 21:51:29 +0000 (-0700) Subject: ProCamera: Add security permission checks for disabling transmit LED X-Git-Tag: android-x86-4.4-r1~412^2^2~29^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=03ac850527ffb90348dcdaad95caceb97649fd6b;p=android-x86%2Fframeworks-av.git ProCamera: Add security permission checks for disabling transmit LED Bug: 8554573 Change-Id: Ie909908a4cab3700bd622282e8342e8fa5b72376 --- diff --git a/services/camera/libcameraservice/ProCamera2Client.cpp b/services/camera/libcameraservice/ProCamera2Client.cpp index 575b075cca..251fdabc87 100644 --- a/services/camera/libcameraservice/ProCamera2Client.cpp +++ b/services/camera/libcameraservice/ProCamera2Client.cpp @@ -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 diff --git a/services/camera/libcameraservice/ProCamera2Client.h b/services/camera/libcameraservice/ProCamera2Client.h index 1dec263b92..faee9f9e75 100644 --- a/services/camera/libcameraservice/ProCamera2Client.h +++ b/services/camera/libcameraservice/ProCamera2Client.h @@ -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. diff --git a/services/camera/libcameraservice/camera2/Parameters.cpp b/services/camera/libcameraservice/camera2/Parameters.cpp index d13fe8bade..a304b35a8e 100644 --- a/services/camera/libcameraservice/camera2/Parameters.cpp +++ b/services/camera/libcameraservice/camera2/Parameters.cpp @@ -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);