aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Essick <essick@google.com>2018-10-12 15:46:15 -0700
committerRay Essick <essick@google.com>2018-10-12 15:52:05 -0700
commit9aa31abee27afa129ebbc80c41097368c68dedfa (patch)
tree688871e02796e20433118f739c0c29dae562ef7b
parenta5e8e5812a11ec9686294de8a5d68aaf2ab72475 (diff)
downloadlibexif-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.c31
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