Skip to content

Commit 887a7b5

Browse files
committed
Fixed bug #77831 - Heap-buffer-overflow in exif_iif_add_value in EXIF
1 parent c684d32 commit 887a7b5

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ PHP NEWS
44

55
- EXIF:
66
. Fixed bug #77753 (Heap-buffer-overflow in php_ifd_get32s). (Stas)
7+
. Fixed bug #77831 (Heap-buffer-overflow in exif_iif_add_value). (Stas)
78

89
- SQLite3:
910
. Added sqlite3.defensive INI directive. (BohwaZ)

ext/exif/exif.c

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,10 +1654,10 @@ static int exif_file_sections_free(image_info_type *ImageInfo)
16541654
/* {{{ exif_iif_add_value
16551655
Add a value to image_info
16561656
*/
1657-
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)
1657+
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)
16581658
{
16591659
size_t idex;
1660-
void *vptr;
1660+
void *vptr, *vptr_end;
16611661
image_info_value *info_value;
16621662
image_info_data *info_data;
16631663
image_info_data *list;
@@ -1679,8 +1679,12 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
16791679

16801680
switch (format) {
16811681
case TAG_FMT_STRING:
1682+
if (length > value_len) {
1683+
exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len);
1684+
value = NULL;
1685+
}
16821686
if (value) {
1683-
length = php_strnlen(value, length);
1687+
length = (int)php_strnlen(value, length);
16841688
info_value->s = estrndup(value, length);
16851689
info_data->length = length;
16861690
} else {
@@ -1702,6 +1706,10 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
17021706
if (!length)
17031707
break;
17041708
case TAG_FMT_UNDEFINED:
1709+
if (length > value_len) {
1710+
exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "length > value_len: %d > %zu", length, value_len);
1711+
value = NULL;
1712+
}
17051713
if (value) {
17061714
if (tag == TAG_MAKER_NOTE) {
17071715
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
17321740
} else {
17331741
info_value = &info_data->value;
17341742
}
1743+
vptr_end = value+value_len;
17351744
for (idex=0,vptr=value; idex<(size_t)length; idex++,vptr=(char *) vptr + php_tiff_bytes_per_format[format]) {
1745+
if (vptr_end - vptr < php_tiff_bytes_per_format[format]) {
1746+
exif_error_docref("exif_iif_add_value" EXIFERR_CC, image_info, E_WARNING, "Value too short");
1747+
break;
1748+
}
17361749
if (length>1) {
17371750
info_value = &info_data->value.list[idex];
17381751
}
@@ -1768,7 +1781,7 @@ static void exif_iif_add_value(image_info_type *image_info, int section_index, c
17681781
php_error_docref(NULL, E_WARNING, "Found value of type single");
17691782
#endif
17701783
info_value->f = *(float *)value;
1771-
1784+
break;
17721785
case TAG_FMT_DOUBLE:
17731786
#ifdef EXIF_DEBUG
17741787
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
17861799
/* {{{ exif_iif_add_tag
17871800
Add a tag from IFD to image_info
17881801
*/
1789-
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)
1802+
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)
17901803
{
1791-
exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, image_info->motorola_intel);
1804+
exif_iif_add_value(image_info, section_index, name, tag, format, (int)length, value, value_len, image_info->motorola_intel);
17921805
}
17931806
/* }}} */
17941807

@@ -2209,7 +2222,7 @@ static void add_assoc_image_info(zval *value, int sub_array, image_info_type *im
22092222
*/
22102223
static void exif_process_COM (image_info_type *image_info, char *value, size_t length)
22112224
{
2212-
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2);
2225+
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length-2, value+2, length-2);
22132226
}
22142227
/* }}} */
22152228

@@ -2224,17 +2237,17 @@ static void exif_process_CME (image_info_type *image_info, char *value, size_t l
22242237
if (length>3) {
22252238
switch(value[2]) {
22262239
case 0:
2227-
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value);
2240+
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, length, value), length;
22282241
break;
22292242
case 1:
2230-
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value);
2243+
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_STRING, length, value, length);
22312244
break;
22322245
default:
22332246
php_error_docref(NULL, E_NOTICE, "Undefined JPEG2000 comment encoding");
22342247
break;
22352248
}
22362249
} else {
2237-
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, 0, NULL);
2250+
exif_iif_add_tag(image_info, SECTION_COMMENT, "Comment", TAG_COMPUTED_VALUE, TAG_FMT_UNDEFINED, 0, NULL, 0);
22382251
php_error_docref(NULL, E_NOTICE, "JPEG2000 comment section too small");
22392252
}
22402253
}
@@ -2827,7 +2840,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
28272840
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)
28282841
{
28292842
size_t length;
2830-
int tag, format, components;
2843+
unsigned int tag, format, components;
28312844
char *value_ptr, tagname[64], cbuf[32], *outside=NULL;
28322845
size_t byte_count, offset_val, fpos, fgot;
28332846
int64_t byte_count_signed;
@@ -3138,7 +3151,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
31383151
}
31393152
}
31403153
}
3141-
exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table), tag, format, components, value_ptr);
3154+
exif_iif_add_tag(ImageInfo, section_index, exif_get_tagname(tag, tagname, sizeof(tagname), tag_table), tag, format, components, value_ptr, byte_count);
31423155
EFREE_IF(outside);
31433156
return TRUE;
31443157
}
@@ -3296,10 +3309,10 @@ static void exif_process_APP12(image_info_type *ImageInfo, char *buffer, size_t
32963309
size_t l1, l2=0;
32973310

32983311
if ((l1 = php_strnlen(buffer+2, length-2)) > 0) {
3299-
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2);
3312+
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Company", TAG_NONE, TAG_FMT_STRING, l1, buffer+2, l1);
33003313
if (length > 2+l1+1) {
33013314
l2 = php_strnlen(buffer+2+l1+1, length-2-l1-1);
3302-
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1);
3315+
exif_iif_add_tag(ImageInfo, SECTION_APP12, "Info", TAG_NONE, TAG_FMT_STRING, l2, buffer+2+l1+1, l2);
33033316
}
33043317
}
33053318
#ifdef EXIF_DEBUG
@@ -4100,7 +4113,7 @@ PHP_FUNCTION(exif_read_data)
41004113
if (ImageInfo.Thumbnail.size) {
41014114
if (read_thumbnail) {
41024115
/* not exif_iif_add_str : this is a buffer */
4103-
exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data);
4116+
exif_iif_add_tag(&ImageInfo, SECTION_THUMBNAIL, "THUMBNAIL", TAG_NONE, TAG_FMT_UNDEFINED, ImageInfo.Thumbnail.size, ImageInfo.Thumbnail.data, ImageInfo.Thumbnail.size);
41044117
}
41054118
if (!ImageInfo.Thumbnail.width || !ImageInfo.Thumbnail.height) {
41064119
/* try to evaluate if thumbnail data is present */

ext/exif/tests/bug77831.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #77831 (Heap-buffer-overflow in exif_iif_add_value in EXIF)
3+
--SKIPIF--
4+
<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
5+
--FILE--
6+
<?php
7+
var_dump(exif_read_data(__DIR__."/bug77831.tiff"));
8+
?>
9+
DONE
10+
--EXPECTF--
11+
%A
12+
bool(false)
13+
DONE

ext/exif/tests/bug77831.tiff

49 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)