From eebcbd5de38a0f1c2876035402cb770e37476519 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 17 Jul 2016 16:34:21 -0700 Subject: Fix bug #72603: Out of bound read in exif_process_IFD_in_MAKERNOTE --- ext/exif/exif.c | 22 ++++++++++++++++++++-- ext/exif/tests/bug72603.jpeg | Bin 0 -> 3711 bytes ext/exif/tests/bug72603.phpt | 11 +++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 ext/exif/tests/bug72603.jpeg create mode 100644 ext/exif/tests/bug72603.phpt (limited to 'ext/exif') diff --git a/ext/exif/exif.c b/ext/exif/exif.c index f366acc552..760e7460c3 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2742,6 +2742,12 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu break; } + if (maker_note->offset >= value_len) { + /* Do not go past the value end */ + exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X offset 0x%04X", value_len, maker_note->offset); + return FALSE; + } + dir_start = value_ptr + maker_note->offset; #ifdef EXIF_DEBUG @@ -2770,10 +2776,19 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu offset_base = value_ptr; break; case MN_OFFSET_GUESS: + if (maker_note->offset + 10 + 4 >= value_len) { + /* Can not read dir_start+10 since it's beyond value end */ + exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data too short: 0x%04X", value_len); + return FALSE; + } offset_diff = 2 + NumDirEntries*12 + 4 - php_ifd_get32u(dir_start+10, ImageInfo->motorola_intel); #ifdef EXIF_DEBUG exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Using automatic offset correction: 0x%04X", ((int)dir_start-(int)offset_base+maker_note->offset+displacement) + offset_diff); #endif + if (offset_diff < 0 || offset_diff >= value_len ) { + exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "IFD data bad offset: 0x%04X length 0x%04X", offset_diff, value_len); + return FALSE; + } offset_base = value_ptr + offset_diff; break; default: @@ -2782,7 +2797,7 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu } if ((2+NumDirEntries*12) > value_len) { - exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + x%04X*12 = x%04X > x%04X", NumDirEntries, 2+NumDirEntries*12, value_len); + exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len); return FALSE; } @@ -3068,7 +3083,10 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha break; case TAG_MAKER_NOTE: - exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement TSRMLS_CC); + if (!exif_process_IFD_in_MAKERNOTE(ImageInfo, value_ptr, byte_count, offset_base, IFDlength, displacement TSRMLS_CC)) { + EFREE_IF(outside); + return FALSE; + } break; case TAG_EXIF_IFD_POINTER: diff --git a/ext/exif/tests/bug72603.jpeg b/ext/exif/tests/bug72603.jpeg new file mode 100644 index 0000000000..1764c805fb Binary files /dev/null and b/ext/exif/tests/bug72603.jpeg differ diff --git a/ext/exif/tests/bug72603.phpt b/ext/exif/tests/bug72603.phpt new file mode 100644 index 0000000000..a4295f9848 --- /dev/null +++ b/ext/exif/tests/bug72603.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #72603 (Out of bound read in exif_process_IFD_in_MAKERNOTE) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: exif_read_data(bug72603.jpeg): IFD data bad offset: 0x058C length 0x001C in %s/bug72603.php on line %d +int(13) \ No newline at end of file -- cgit v1.2.1 From 41131cd41d2fd2e0c2f332a27988df75659c42e4 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 18 Jul 2016 23:21:51 -0700 Subject: Fix bug #72618: NULL Pointer Dereference in exif_process_user_comment --- ext/exif/exif.c | 17 +++++++++++------ ext/exif/tests/bug72618.jpg | Bin 0 -> 3711 bytes ext/exif/tests/bug72618.phpt | 11 +++++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 ext/exif/tests/bug72618.jpg create mode 100644 ext/exif/tests/bug72618.phpt (limited to 'ext/exif') diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 760e7460c3..74b652b3eb 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -2623,6 +2623,7 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP *pszEncoding = NULL; /* Copy the comment */ if (ByteCount>=8) { + const zend_encoding *from, *to; if (!memcmp(szValuePtr, "UNICODE\0", 8)) { *pszEncoding = estrdup((const char*)szValuePtr); szValuePtr = szValuePtr+8; @@ -2643,14 +2644,16 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP } else { decode = ImageInfo->decode_unicode_le; } + to = zend_multibyte_fetch_encoding(ImageInfo->encode_unicode TSRMLS_CC); + from = zend_multibyte_fetch_encoding(decode TSRMLS_CC); /* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */ - if (zend_multibyte_encoding_converter( + if (!to || !from || zend_multibyte_encoding_converter( (unsigned char**)pszInfoPtr, &len, (unsigned char*)szValuePtr, ByteCount, - zend_multibyte_fetch_encoding(ImageInfo->encode_unicode TSRMLS_CC), - zend_multibyte_fetch_encoding(decode TSRMLS_CC) + to, + from TSRMLS_CC) == (size_t)-1) { len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount); } @@ -2665,13 +2668,15 @@ static int exif_process_user_comment(image_info_type *ImageInfo, char **pszInfoP szValuePtr = szValuePtr+8; ByteCount -= 8; /* XXX this will fail again if encoding_converter returns on error something different than SIZE_MAX */ - if (zend_multibyte_encoding_converter( + to = zend_multibyte_fetch_encoding(ImageInfo->encode_jis TSRMLS_CC); + from = zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le TSRMLS_CC); + if (!to || !from || zend_multibyte_encoding_converter( (unsigned char**)pszInfoPtr, &len, (unsigned char*)szValuePtr, ByteCount, - zend_multibyte_fetch_encoding(ImageInfo->encode_jis TSRMLS_CC), - zend_multibyte_fetch_encoding(ImageInfo->motorola_intel ? ImageInfo->decode_jis_be : ImageInfo->decode_jis_le TSRMLS_CC) + to, + from TSRMLS_CC) == (size_t)-1) { len = exif_process_string_raw(pszInfoPtr, szValuePtr, ByteCount); } diff --git a/ext/exif/tests/bug72618.jpg b/ext/exif/tests/bug72618.jpg new file mode 100644 index 0000000000..0a61ae2e02 Binary files /dev/null and b/ext/exif/tests/bug72618.jpg differ diff --git a/ext/exif/tests/bug72618.phpt b/ext/exif/tests/bug72618.phpt new file mode 100644 index 0000000000..424c0ec402 --- /dev/null +++ b/ext/exif/tests/bug72618.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug 72618 (NULL Pointer Dereference in exif_process_user_comment) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: exif_read_data(bug72618.jpg): IFD data bad offset: 0x058E length 0x0030 in %s/bug72618.php on line %d +int(13) \ No newline at end of file -- cgit v1.2.1 From 1364742be9757e594fd1b203d45805106ecd31c7 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 18 Jul 2016 23:30:51 -0700 Subject: Fix tests --- ext/exif/tests/bug54002.phpt | 6 +----- ext/exif/tests/bug62523_2.phpt | 6 ++++-- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'ext/exif') diff --git a/ext/exif/tests/bug54002.phpt b/ext/exif/tests/bug54002.phpt index c51fa58897..8f85339190 100644 --- a/ext/exif/tests/bug54002.phpt +++ b/ext/exif/tests/bug54002.phpt @@ -13,8 +13,4 @@ exif_read_data(__DIR__ . '/bug54002_2.jpeg'); --EXPECTF-- Warning: exif_read_data(bug54002_1.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d -Warning: exif_read_data(bug54002_1.jpeg): Process tag(xA000=FlashPixVer): Illegal pointer offset(%s) in %sbug54002.php on line %d - -Warning: exif_read_data(bug54002_2.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d - -Warning: exif_read_data(bug54002_2.jpeg): Process tag(xA000=FlashPixVer): Illegal pointer offset(%s) in %sbug54002.php on line %d +Warning: exif_read_data(bug54002_2.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count in %sbug54002.php on line %d \ No newline at end of file diff --git a/ext/exif/tests/bug62523_2.phpt b/ext/exif/tests/bug62523_2.phpt index ddc8ae824e..c533d42652 100644 --- a/ext/exif/tests/bug62523_2.phpt +++ b/ext/exif/tests/bug62523_2.phpt @@ -10,7 +10,9 @@ echo "Test\n"; var_dump(count(exif_read_data(__DIR__."/bug62523_2.jpg"))); ?> Done ---EXPECT-- +--EXPECTF-- Test -int(76) + +Warning: exif_read_data(bug62523_2.jpg): IFD data bad offset: 0xADB23672 length 0x0D94 in %s/bug62523_2.php on line %d +int(30) Done -- cgit v1.2.1