summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJessica Wagantall <jwagantall@cyngn.com>2016-10-06 11:50:36 -0700
committerJessica Wagantall <jwagantall@cyngn.com>2016-10-06 11:50:36 -0700
commit69c4724d5c9f0335258d9219fe1bb285f887495d (patch)
tree6d7203902cb7b1188659ebc1ee905d79e370aa2e
parent92d65f3fd2fdf37b3593ba60a50cd5f551e7f238 (diff)
parentf3723a4b7f99c322b87c18a970b428f4b2de366d (diff)
downloadandroid_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.c71
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,