summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2019-04-02 00:12:26 -0700
committerSara Golemon <pollita@php.net>2019-04-02 11:01:16 -0400
commit330f1716df49c0d3474c18b6dcd370a9dcf57422 (patch)
tree6a905cff8b4200ec26f2e06b29b3b67be430585a
parent1c0d06441aefee18b30520e2b1ae89cbfcf56a59 (diff)
downloadphp-git-330f1716df49c0d3474c18b6dcd370a9dcf57422.tar.gz
Fixed bug #77831 - Heap-buffer-overflow in exif_iif_add_value in EXIF
-rw-r--r--NEWS4
-rw-r--r--ext/exif/exif.c43
-rw-r--r--ext/exif/tests/bug77831.phpt13
-rw-r--r--ext/exif/tests/bug77831.tiffbin0 -> 49 bytes
4 files changed, 45 insertions, 15 deletions
diff --git a/NEWS b/NEWS
index f38de858c7..1761619898 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,10 @@ PHP NEWS
. Fixed bug #75113 (Added DatePeriod::getRecurrences() method). (Ignace
Nyamagana Butera)
+- EXIF:
+ . Fixed bug #77753 (Heap-buffer-overflow in php_ifd_get32s). (Stas)
+ . Fixed bug #77831 (Heap-buffer-overflow in exif_iif_add_value). (Stas)
+
- FPM:
. Fixed bug #77677 (FPM fails to build on AIX due to missing WCOREDUMP).
(Kevin Adler)
diff --git a/ext/exif/exif.c b/ext/exif/exif.c
index 407145fffc..75f59d71c9 100644
--- a/ext/exif/exif.c
+++ b/ext/exif/exif.c
@@ -2062,10 +2062,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;
@@ -2087,8 +2087,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 {
@@ -2110,6 +2114,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);
@@ -2140,7 +2148,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];
}
@@ -2176,7 +2189,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");
@@ -2194,9 +2207,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);
}
/* }}} */
@@ -2617,7 +2630,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);
}
/* }}} */
@@ -2632,17 +2645,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");
}
}
@@ -3240,7 +3253,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;
@@ -3555,7 +3568,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;
}
@@ -3717,10 +3730,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
@@ -4588,7 +4601,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 0000000000..d868d47a1f
--- /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
diff --git a/ext/exif/tests/bug77831.tiff b/ext/exif/tests/bug77831.tiff
new file mode 100644
index 0000000000..c7e9f4472b
--- /dev/null
+++ b/ext/exif/tests/bug77831.tiff
Binary files differ