186 lines
8.3 KiB
Diff
186 lines
8.3 KiB
Diff
From 887a7b571407f7a49a5e7cf1e612d21ef83fedb4 Mon Sep 17 00:00:00 2001
|
|
From: Stanislav Malyshev <stas@php.net>
|
|
Date: Tue, 2 Apr 2019 00:12:26 -0700
|
|
Subject: [PATCH] Fixed bug #77831 - Heap-buffer-overflow in exif_iif_add_value
|
|
in EXIF
|
|
|
|
---
|
|
NEWS | 1 +
|
|
ext/exif/exif.c | 43 ++++++++++++++++++++++++++++---------------
|
|
ext/exif/tests/bug77831.phpt | 13 +++++++++++++
|
|
ext/exif/tests/bug77831.tiff | Bin 0 -> 49 bytes
|
|
4 files changed, 42 insertions(+), 15 deletions(-)
|
|
create mode 100644 ext/exif/tests/bug77831.phpt
|
|
create mode 100644 ext/exif/tests/bug77831.tiff
|
|
|
|
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
|
|
index 0b5bb5a..408bf03 100644
|
|
--- a/ext/exif/exif.c
|
|
+++ b/ext/exif/exif.c
|
|
@@ -1654,10 +1654,10 @@ static int exif_file_sections_free(image_info_type *ImageInfo)
|
|
/* {{{ exif_iif_add_value
|
|
Add a value to image_info
|
|
*/
|
|
-static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, int motorola_intel)
|
|
+static void exif_iif_add_value(image_info_type *image_info, int section_index, char *name, int tag, int format, int length, void* value, size_t value_len, int motorola_intel)
|
|
{
|
|
size_t idex;
|
|
- void *vptr;
|
|
+ void *vptr, *vptr_end;
|
|
image_info_value *info_value;
|
|
image_info_data *info_data;
|
|
image_info_data *list;
|
|
@@ -1679,8 +1679,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
|
|
|
switch (format) {
|
|
case TAG_FMT_STRING:
|
|
+ if (length > value_len) {
|
|
+ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len);
|
|
+ value = NULL;
|
|
+ }
|
|
if (value) {
|
|
- length = php_strnlen(value, length);
|
|
+ length = (int)php_strnlen(value, length);
|
|
info_value->s = estrndup(value, length);
|
|
info_data->length = length;
|
|
} else {
|
|
@@ -1702,6 +1706,10 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
|
if (!length)
|
|
break;
|
|
case TAG_FMT_UNDEFINED:
|
|
+ if (length > value_len) {
|
|
+ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len);
|
|
+ value = NULL;
|
|
+ }
|
|
if (value) {
|
|
if (tag == TAG_MAKER_NOTE) {
|
|
length = (int) php_strnlen(value, length);
|
|
@@ -1732,7 +1740,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
|
} else {
|
|
info_value = &info_data->value;
|
|
}
|
|
+ vptr_end = value+value_len;
|
|
for (idex=0,vptr=value; idex<(size_t)length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) {
|
|
+ if (vptr_end - vptr < php_tiff_bytes_per_format[format]) {
|
|
+ exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "Value too short");
|
|
+ break;
|
|
+ }
|
|
if (length>1) {
|
|
info_value = &info_data->value.list[idex];
|
|
}
|
|
@@ -1768,7 +1781,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
|
php_error_docref(NULL, E_WARNING, "Found value of type single");
|
|
#endif
|
|
info_value->f = *(float *)value;
|
|
-
|
|
+ break;
|
|
case TAG_FMT_DOUBLE:
|
|
#ifdef EXIF_DEBUG
|
|
php_error_docref(NULL, E_WARNING, "Found value of type double");
|
|
@@ -1786,9 +1799,9 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
|
|
/* {{{ exif_iif_add_tag
|
|
Add a tag from IFD to image_info
|
|
*/
|
|
-static void exif_iif_add_tag(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t length, void* value)
|
|
+static void exif_iif_add_tag(image_info_type *image_info, int section_index, char *name, int tag, int format, size_t length, void* value, size_t value_len)
|
|
{
|
|
- exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, image_info->motorola_intel);
|
|
+ exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, value_len, image_info->motorola_intel);
|
|
}
|
|
/* }}} */
|
|
|
|
@@ -2209,7 +2222,7 @@ static void add_assoc_image_info(zval *value, int sub_array, image_info_type *im
|
|
*/
|
|
static void exif_process_COM (image_info_type *image_info, char *value, size_t length)
|
|
{
|
|
- exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2);
|
|
+ exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2, length-2);
|
|
}
|
|
/* }}} */
|
|
|
|
@@ -2224,17 +2237,17 @@ static void exif_process_CME (image_info_type *image_info, char *value, size_t l
|
|
if (length>3) {
|
|
switch(value[2]) {
|
|
case 0:
|
|
- exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value);
|
|
+ exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value), length;
|
|
break;
|
|
case 1:
|
|
- exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value);
|
|
+ exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value, length);
|
|
break;
|
|
default:
|
|
php_error_docref(NULL, E_NOTICE, "Undefined JPEG2000 comment encoding");
|
|
break;
|
|
}
|
|
} else {
|
|
- exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, 0, NULL);
|
|
+ exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, 0, NULL, 0);
|
|
php_error_docref(NULL, E_NOTICE, "JPEG2000 comment section too small");
|
|
}
|
|
}
|
|
@@ -2827,7 +2840,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
|
|
static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, char *offset_base, size_t IFDlength, size_t displacement, int section_index, int ReadNextIFD, tag_table_type tag_table)
|
|
{
|
|
size_t length;
|
|
- int tag, format, components;
|
|
+ unsigned int tag, format, components;
|
|
char *value_ptr, tagname[64], cbuf[32], *outside=NULL;
|
|
size_t byte_count, offset_val, fpos, fgot;
|
|
int64_t byte_count_signed;
|
|
@@ -3138,7 +3151,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|
}
|
|
}
|
|
}
|
|
- exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table), tag, format, components, value_ptr);
|
|
+ exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table), tag, format, components, value_ptr, byte_count);
|
|
EFREE_IF(outside);
|
|
return TRUE;
|
|
}
|
|
@@ -3296,10 +3309,10 @@ static void exif_process_APP12(image_info_type *ImageInfo, char *buffer, size_t
|
|
size_t l1, l2=0;
|
|
|
|
if ((l1 = php_strnlen(buffer+2, length-2)) > 0) {
|
|
- exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2);
|
|
+ exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2, l1);
|
|
if (length > 2+l1+1) {
|
|
l2 = php_strnlen(buffer+2+l1+1, length-2-l1-1);
|
|
- exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1);
|
|
+ exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1, l2);
|
|
}
|
|
}
|
|
#ifdef EXIF_DEBUG
|
|
@@ -4100,7 +4113,7 @@ PHP_FUNCTION(exif_read_data)
|
|
if (ImageInfo.Thumbnail.size) {
|
|
if (read_thumbnail) {
|
|
/* not exif_iif_add_str : this is a buffer */
|
|
- exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data);
|
|
+ exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data, ImageInfo.Thumbnail.size);
|
|
}
|
|
if (!ImageInfo.Thumbnail.width || !ImageInfo.Thumbnail.height) {
|
|
/* try to evaluate if thumbnail data is present */
|
|
diff --git a/ext/exif/tests/bug77831.phpt b/ext/exif/tests/bug77831.phpt
|
|
new file mode 100644
|
|
index 0000000..d868d47
|
|
--- /dev/null
|
|
+++ b/ext/exif/tests/bug77831.phpt
|
|
@@ -0,0 +1,13 @@
|
|
+--TEST--
|
|
+Bug #77831 (Heap-buffer-overflow in exif_iif_add_value in EXIF)
|
|
+--SKIPIF--
|
|
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
|
|
+--FILE--
|
|
+<?php
|
|
+var_dump(exif_read_data(__DIR__."/bug77831.tiff"));
|
|
+?>
|
|
+DONE
|
|
+--EXPECTF--
|
|
+%A
|
|
+bool(false)
|
|
+DONE
|
|
\ No newline at end of file
|
|
|
|
--
|
|
2.1.4
|
|
|