summaryrefslogtreecommitdiffstats
path: root/camera/IProCameraUser.cpp
diff options
context:
space:
mode:
authorIgor Murashkin <iam@google.com>2013-04-30 18:18:06 -0700
committerIgor Murashkin <iam@google.com>2013-05-02 18:03:13 -0700
commite2d1e3d0436aec645739c65e6d3131dd814f40a1 (patch)
tree2c5468dc1abbd5455589aee54b41e0273e16368b /camera/IProCameraUser.cpp
parentd8c7ad1cbc2e6830560a085380a5828cc3d41010 (diff)
downloadframeworks_av-e2d1e3d0436aec645739c65e6d3131dd814f40a1.zip
frameworks_av-e2d1e3d0436aec645739c65e6d3131dd814f40a1.tar.gz
frameworks_av-e2d1e3d0436aec645739c65e6d3131dd814f40a1.tar.bz2
camera: Use new camera_metadata structure validation functions
* Reject unvalidated metadata across binder boundaries * Sanity check in-process CameraMetadata when mutating data Bug: 8713951 Change-Id: I121d8e15f8fdc9cdbbaf27dfd947813e11831e1c
Diffstat (limited to 'camera/IProCameraUser.cpp')
-rw-r--r--camera/IProCameraUser.cpp63
1 files changed, 48 insertions, 15 deletions
diff --git a/camera/IProCameraUser.cpp b/camera/IProCameraUser.cpp
index 0c94bd4..4c4dec3 100644
--- a/camera/IProCameraUser.cpp
+++ b/camera/IProCameraUser.cpp
@@ -50,17 +50,30 @@ enum {
* Caller becomes the owner of the new metadata
* 'const Parcel' doesnt prevent us from calling the read functions.
* which is interesting since it changes the internal state
+ *
+ * NULL can be returned when no metadata was sent, OR if there was an issue
+ * unpacking the serialized data (i.e. bad parcel or invalid structure).
*/
void readMetadata(const Parcel& data, camera_metadata_t** out) {
- camera_metadata_t* metadata;
+
+ status_t err = OK;
+
+ camera_metadata_t* metadata = NULL;
+
+ if (out) {
+ *out = NULL;
+ }
// arg0 = metadataSize (int32)
- size_t metadataSize = static_cast<size_t>(data.readInt32());
+ int32_t metadataSizeTmp = -1;
+ if ((err = data.readInt32(&metadataSizeTmp)) != OK) {
+ ALOGE("%s: Failed to read metadata size (error %d %s)",
+ __FUNCTION__, err, strerror(-err));
+ return;
+ }
+ const size_t metadataSize = static_cast<size_t>(metadataSizeTmp);
if (metadataSize == 0) {
- if (out) {
- *out = NULL;
- }
return;
}
@@ -70,21 +83,23 @@ void readMetadata(const Parcel& data, camera_metadata_t** out) {
ReadableBlob blob;
// arg1 = metadata (blob)
- {
- data.readBlob(metadataSize, &blob);
+ do {
+ if ((err = data.readBlob(metadataSize, &blob)) != OK) {
+ ALOGE("%s: Failed to read metadata blob (sized %d). Possible "
+ " serialization bug. Error %d %s",
+ __FUNCTION__, metadataSize, err, strerror(-err));
+ break;
+ }
const camera_metadata_t* tmp =
reinterpret_cast<const camera_metadata_t*>(blob.data());
- size_t entry_capacity = get_camera_metadata_entry_capacity(tmp);
- size_t data_capacity = get_camera_metadata_data_capacity(tmp);
- metadata = allocate_camera_metadata(entry_capacity, data_capacity);
- copy_camera_metadata(metadata, metadataSize, tmp);
- }
+ metadata = allocate_copy_camera_metadata_checked(tmp, metadataSize);
+ } while(0);
blob.release();
if (out) {
*out = metadata;
- } else {
+ } else if (metadata != NULL) {
free_camera_metadata(metadata);
}
}
@@ -95,14 +110,13 @@ void readMetadata(const Parcel& data, camera_metadata_t** out) {
*/
void writeMetadata(Parcel& data, camera_metadata_t* metadata) {
// arg0 = metadataSize (int32)
- size_t metadataSize;
if (metadata == NULL) {
data.writeInt32(0);
return;
}
- metadataSize = get_camera_metadata_compact_size(metadata);
+ const size_t metadataSize = get_camera_metadata_compact_size(metadata);
data.writeInt32(static_cast<int32_t>(metadataSize));
// arg1 = metadata (blob)
@@ -110,6 +124,25 @@ void writeMetadata(Parcel& data, camera_metadata_t* metadata) {
{
data.writeBlob(metadataSize, &blob);
copy_camera_metadata(blob.data(), metadataSize, metadata);
+
+ IF_ALOGV() {
+ if (validate_camera_metadata_structure(
+ (const camera_metadata_t*)blob.data(),
+ &metadataSize) != OK) {
+ ALOGV("%s: Failed to validate metadata %p after writing blob",
+ __FUNCTION__, blob.data());
+ } else {
+ ALOGV("%s: Metadata written to blob. Validation success",
+ __FUNCTION__);
+ }
+ }
+
+ // Not too big of a problem since receiving side does hard validation
+ if (validate_camera_metadata_structure(metadata, &metadataSize) != OK) {
+ ALOGW("%s: Failed to validate metadata %p before writing blob",
+ __FUNCTION__, metadata);
+ }
+
}
blob.release();
}