|
22 | 22 | #include <stdlib.h>
|
23 | 23 | #include <errno.h>
|
24 | 24 |
|
25 |
| -#define OK 0 |
26 |
| -#define ERROR 1 |
27 |
| -#define NOT_FOUND -ENOENT |
| 25 | +#define OK 0 |
| 26 | +#define ERROR 1 |
| 27 | +#define NOT_FOUND -ENOENT |
| 28 | +#define SN_EVENT_LOG_ID 0x534e4554 |
28 | 29 |
|
29 | 30 | #define _Alignas(T) \
|
30 | 31 | ({struct _AlignasStruct { char c; T field; }; \
|
@@ -291,6 +292,38 @@ camera_metadata_t* copy_camera_metadata(void *dst, size_t dst_size,
|
291 | 292 | return metadata;
|
292 | 293 | }
|
293 | 294 |
|
| 295 | +// This method should be used when the camera metadata cannot be trusted. For example, when it's |
| 296 | +// read from Parcel. |
| 297 | +static int validate_and_calculate_camera_metadata_entry_data_size(size_t *data_size, uint8_t type, |
| 298 | + size_t data_count) { |
| 299 | + if (type >= NUM_TYPES) return ERROR; |
| 300 | + |
| 301 | + // Check for overflow |
| 302 | + if (data_count != 0 && |
| 303 | + camera_metadata_type_size[type] > (SIZE_MAX - DATA_ALIGNMENT + 1) / data_count) { |
| 304 | + android_errorWriteLog(SN_EVENT_LOG_ID, "30741779"); |
| 305 | + return ERROR; |
| 306 | + } |
| 307 | + |
| 308 | + size_t data_bytes = data_count * camera_metadata_type_size[type]; |
| 309 | + |
| 310 | + if (data_size) { |
| 311 | + *data_size = data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); |
| 312 | + } |
| 313 | + |
| 314 | + return OK; |
| 315 | +} |
| 316 | + |
| 317 | +size_t calculate_camera_metadata_entry_data_size(uint8_t type, |
| 318 | + size_t data_count) { |
| 319 | + if (type >= NUM_TYPES) return 0; |
| 320 | + |
| 321 | + size_t data_bytes = data_count * |
| 322 | + camera_metadata_type_size[type]; |
| 323 | + |
| 324 | + return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); |
| 325 | +} |
| 326 | + |
294 | 327 | int validate_camera_metadata_structure(const camera_metadata_t *metadata,
|
295 | 328 | const size_t *expected_size) {
|
296 | 329 |
|
@@ -400,9 +433,13 @@ int validate_camera_metadata_structure(const camera_metadata_t *metadata,
|
400 | 433 | return ERROR;
|
401 | 434 | }
|
402 | 435 |
|
403 |
| - size_t data_size = |
404 |
| - calculate_camera_metadata_entry_data_size(entry.type, |
405 |
| - entry.count); |
| 436 | + size_t data_size; |
| 437 | + if (validate_and_calculate_camera_metadata_entry_data_size(&data_size, entry.type, |
| 438 | + entry.count) != OK) { |
| 439 | + ALOGE("%s: Entry data size is invalid. type: %u count: %u", __FUNCTION__, entry.type, |
| 440 | + entry.count); |
| 441 | + return ERROR; |
| 442 | + } |
406 | 443 |
|
407 | 444 | if (data_size != 0) {
|
408 | 445 | camera_metadata_data_t *data =
|
@@ -492,14 +529,6 @@ camera_metadata_t *clone_camera_metadata(const camera_metadata_t *src) {
|
492 | 529 | return clone;
|
493 | 530 | }
|
494 | 531 |
|
495 |
| -size_t calculate_camera_metadata_entry_data_size(uint8_t type, |
496 |
| - size_t data_count) { |
497 |
| - if (type >= NUM_TYPES) return 0; |
498 |
| - size_t data_bytes = data_count * |
499 |
| - camera_metadata_type_size[type]; |
500 |
| - return data_bytes <= 4 ? 0 : ALIGN_TO(data_bytes, DATA_ALIGNMENT); |
501 |
| -} |
502 |
| - |
503 | 532 | static int add_camera_metadata_entry_raw(camera_metadata_t *dst,
|
504 | 533 | uint32_t tag,
|
505 | 534 | uint8_t type,
|
|
0 commit comments