diff options
author | Steve Kondik <steve@cyngn.com> | 2016-10-04 13:17:48 -0700 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2016-10-04 13:17:48 -0700 |
commit | ee795e185b6de31dba0014f22059a3d0ab590649 (patch) | |
tree | 92e26744b0b83bb73ac87cf52f1f8d96ba5e7c0f | |
parent | 8f6ef0747dd2a24cbe47b23cacd19fbdf827198f (diff) | |
parent | a0cbcf8be808d0204ce4f42ba23452bf6134ad16 (diff) | |
download | android_system_media-cm-14.0.tar.gz android_system_media-cm-14.0.tar.bz2 android_system_media-cm-14.0.zip |
Merge tag 'android-7.0.0_r14' of https://android.googlesource.com/platform/system/media into HEADcm-14.0
Android 7.0.0 Release 14 (NBD90Z)
# gpg: Signature made Tue 04 Oct 2016 11:26:43 AM PDT using DSA key ID 9AB10E78
# gpg: Can't check signature: public key not found
-rw-r--r-- | camera/src/camera_metadata.c | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/camera/src/camera_metadata.c b/camera/src/camera_metadata.c index c58a9669..a6b69042 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,15 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata, return ERROR; } - const metadata_uptrdiff_t entries_end = - metadata->entries_start + metadata->entry_capacity; + 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 +455,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 +504,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 +557,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, |