diff options
author | Jessica Wagantall <jwagantall@cyngn.com> | 2016-10-06 11:50:36 -0700 |
---|---|---|
committer | Jessica Wagantall <jwagantall@cyngn.com> | 2016-10-06 11:50:36 -0700 |
commit | 69c4724d5c9f0335258d9219fe1bb285f887495d (patch) | |
tree | 6d7203902cb7b1188659ebc1ee905d79e370aa2e | |
parent | 92d65f3fd2fdf37b3593ba60a50cd5f551e7f238 (diff) | |
parent | f3723a4b7f99c322b87c18a970b428f4b2de366d (diff) | |
download | android_system_media-69c4724d5c9f0335258d9219fe1bb285f887495d.tar.gz android_system_media-69c4724d5c9f0335258d9219fe1bb285f887495d.tar.bz2 android_system_media-69c4724d5c9f0335258d9219fe1bb285f887495d.zip |
Merge tag 'android-6.0.1_r72' into HEAD
Android 6.0.1 Release 72 (M4B30X)
# gpg: Signature made Tue 04 Oct 2016 09:47:48 AM PDT using DSA key ID 9AB10E78
# gpg: Can't check signature: public key not found
-rw-r--r-- | camera/src/camera_metadata.c | 71 |
1 files changed, 57 insertions, 14 deletions
diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c index eb914eba..82e88da7 100644 --- a/camera/src/camera_metadata.c +++ b/camera/src/camera_metadata.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#define _GNU_SOURCE // for fdprintf #include <inttypes.h> #include <system/camera_metadata.h> #include <camera_metadata_hidden.h> @@ -25,9 +26,10 @@ #include <stdlib.h> #include <errno.h> -#define OK 0 -#define ERROR 1 -#define NOT_FOUND -ENOENT +#define OK 0 +#define ERROR 1 +#define NOT_FOUND -ENOENT +#define SN_EVENT_LOG_ID 0x534e4554 #define ALIGN_TO(val, alignment) \ (((uintptr_t)(val) + ((alignment) - 1)) & ~((alignment) - 1)) @@ -299,6 +301,38 @@ camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size, return metadata; } +// This method should be used when the camera metadata cannot be trusted. For example, when it's +// read from Parcel. +static int validate_and_calculate_camera_metadata_entry_data_size(size_t *data_size, uint8_t type, + size_t data_count) { + if (type >= NUM_TYPES) return ERROR; + + // Check for overflow + if (data_count != 0 && + camera_metadata_type_size[type] > (SIZE_MAX - DATA_ALIGNMENT + 1) / data_count) { + android_errorWriteLog(SN_EVENT_LOG_ID, "30741779"); + return ERROR; + } + + size_t data_bytes = data_count * camera_metadata_type_size[type]; + + if (data_size) { + *data_size = data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); + } + + return OK; +} + +size_t calculate_camera_metadata_entry_data_size(uint8_t type, + size_t data_count) { + if (type >= NUM_TYPES) return 0; + + size_t data_bytes = data_count * + camera_metadata_type_size[type]; + + return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); +} + int validate_camera_metadata_structure(const camera_metadata_t *metadata, const size_t *expected_size) { @@ -357,8 +391,17 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, return ERROR; } + if (metadata->data_count > metadata->data_capacity) { + ALOGE("%s: Data count (%" PRIu32 ") should be <= data capacity " + "(%" PRIu32 ")", + __FUNCTION__, metadata->data_count, metadata->data_capacity); + android_errorWriteLog(SN_EVENT_LOG_ID, "30591838"); + return ERROR; + } const metadata_uptrdiff_t entries_end = metadata->entries_start + metadata->entry_capacity; + + if (entries_end < metadata->entries_start || // overflow check entries_end > metadata->data_start) { @@ -414,9 +457,13 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, return ERROR; } - size_t data_size = - calculate_camera_metadata_entry_data_size(entry.type, - entry.count); + size_t data_size; + if (validate_and_calculate_camera_metadata_entry_data_size(&data_size, entry.type, + entry.count) != OK) { + ALOGE("%s: Entry data size is invalid. type: %u count: %u", __FUNCTION__, entry.type, + entry.count); + return ERROR; + } if (data_size != 0) { camera_metadata_data_t *data = @@ -459,6 +506,10 @@ int append_camera_metadata(camera_metadata_t *dst, const camera_metadata_t *src) { if (dst == NULL || src == NULL ) return ERROR; + // Check for overflow + if (src->entry_count + dst->entry_count < src->entry_count) return ERROR; + if (src->data_count + dst->data_count < src->data_count) return ERROR; + // Check for space if (dst->entry_capacity < src->entry_count + dst->entry_count) return ERROR; if (dst->data_capacity < src->data_count + dst->data_count) return ERROR; @@ -508,14 +559,6 @@ camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) { return clone; } -size_t calculate_camera_metadata_entry_data_size(uint8_t type, - size_t data_count) { - if (type >= NUM_TYPES) return 0; - size_t data_bytes = data_count * - camera_metadata_type_size[type]; - return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); -} - static int add_camera_metadata_entry_raw(camera_metadata_t *dst, uint32_t tag, uint8_t type, |