]> granicus.if.org Git - php/commitdiff
Fix bug #72603: Out of bound read in exif_process_IFD_in_MAKERNOTE
authorStanislav Malyshev <stas@php.net>
Sun, 17 Jul 2016 23:34:21 +0000 (16:34 -0700)
committerStanislav Malyshev <stas@php.net>
Sun, 17 Jul 2016 23:34:21 +0000 (16:34 -0700)
ext/exif/exif.c
ext/exif/tests/bug72603.jpeg [new file with mode: 0644]
ext/exif/tests/bug72603.phpt [new file with mode: 0644]

index f366acc552b833af05c402be1c85c28cfd1581e6..760e7460c3ef9ff6b4ce6e0a76eedcf22ce0b517 100644 (file)
@@ -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 (file)
index 0000000..1764c80
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 (file)
index 0000000..a4295f9
--- /dev/null
@@ -0,0 +1,11 @@
+--TEST--
+Bug #72603 (Out of bound read in exif_process_IFD_in_MAKERNOTE)
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+var_dump(count(exif_read_data(dirname(__FILE__) . "/bug72603.jpeg")));
+?>
+--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