diff options
author | Ray Essick <essick@google.com> | 2018-10-12 15:46:15 -0700 |
---|---|---|
committer | Ray Essick <essick@google.com> | 2018-10-12 15:52:05 -0700 |
commit | 9aa31abee27afa129ebbc80c41097368c68dedfa (patch) | |
tree | 688871e02796e20433118f739c0c29dae562ef7b | |
parent | a5e8e5812a11ec9686294de8a5d68aaf2ab72475 (diff) | |
download | libexif-9aa31abee27afa129ebbc80c41097368c68dedfa.tar.gz |
fix handling of empty exif jpeg data
some cameras are producing empty JPEG exif data (as opposed to
omitting it). The resulting sub-overflow resulted in failure at parsing
exif data for a thumbnail; with sanitizers enabled, it crashes
android.process.media
Bug: 117576575
Test: transfer POC image
-rw-r--r-- | libexif/exif-loader.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/libexif/exif-loader.c b/libexif/exif-loader.c index 317b86b..7aebf1e 100644 --- a/libexif/exif-loader.c +++ b/libexif/exif-loader.c @@ -225,7 +225,7 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len) break; } - for (i = 0; i < sizeof (eld->b); i++) + for (i = 0; i < sizeof (eld->b); i++) { switch (eld->state) { case EL_EXIF_FOUND: if (!exif_loader_copy (eld, eld->b + i, @@ -233,9 +233,19 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len) return 0; return exif_loader_copy (eld, buf, len); case EL_SKIP_BYTES: - eld->size--; - if (!eld->size) - eld->state = EL_READ; + switch (eld->size) { + case 0: + eld->state = EL_READ; + i--; // reprocess this byte + break; + case 1: + eld->size = 0; + eld->state = EL_READ; + break; + default: + eld->size--; + break; + } break; case EL_READ_SIZE_BYTE_24: @@ -255,12 +265,20 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len) switch (eld->data_format) { case EL_DATA_FORMAT_JPEG: eld->state = EL_SKIP_BYTES; - eld->size -= 2; + if (eld->size < 2) { + // Actually it's malformed... + eld->size = 0; + } else + eld->size -= 2; break; case EL_DATA_FORMAT_FUJI_RAW: eld->data_format = EL_DATA_FORMAT_EXIF; eld->state = EL_SKIP_BYTES; - eld->size -= 86; + if (eld->size < 86) { + // Actually it's malformed... + eld->size = 0; + } else + eld->size -= 86; // and put this in an else break; case EL_DATA_FORMAT_EXIF: eld->state = EL_EXIF_FOUND; @@ -304,6 +322,7 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len) return 0; } } + } /* * If we reach this point, the buffer has not been big enough |