]> granicus.if.org Git - php/commitdiff
- fix bug #54002, exif_read_data crashes on crafted tags
authorPierre Joye <pajoye@php.net>
Mon, 14 Feb 2011 09:08:44 +0000 (09:08 +0000)
committerPierre Joye <pajoye@php.net>
Mon, 14 Feb 2011 09:08:44 +0000 (09:08 +0000)
ext/exif/exif.c
ext/exif/tests/bug54002.phpt [new file with mode: 0644]
ext/exif/tests/bug54002_1.jpeg [new file with mode: 0644]
ext/exif/tests/bug54002_2.jpeg [new file with mode: 0644]

index 84fb5e72d7562a239c03d8803a27e74f42aff289..2063180946bc13f7b3738791e2786b0a453c1eac 100644 (file)
 #include "php.h"
 #include "ext/standard/file.h"
 
+#ifdef PHP_WIN32
+include "win32/php_stdint.h"
+#endif
+
 #if HAVE_EXIF
 
 /* When EXIF_DEBUG is defined the module generates a lot of debug messages
@@ -2817,6 +2821,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
        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;
        xp_field_type *tmp_xp;
 #ifdef EXIF_DEBUG
        char *dump_data;
@@ -2841,13 +2846,19 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
                /*return TRUE;*/
        }
 
-       byte_count = components * php_tiff_bytes_per_format[format];
+       if (components < 0) {
+               exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal byte_count(%ld)", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC), byte_count);
+               return FALSE;
+       }
+       byte_count_signed = (int64_t)components * php_tiff_bytes_per_format[format];
 
-       if ((ssize_t)byte_count < 0) {
+       if (byte_count_signed < 0 || (byte_count_signed > 2147483648)) {
                exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Illegal byte_count(%ld)", tag, exif_get_tagname(tag, tagname, -12, tag_table TSRMLS_CC), byte_count);
                return FALSE;
        }
 
+       byte_count = (size_t)byte_count_signed;
+
        if (byte_count > 4) {
                offset_val = php_ifd_get32u(dir_entry+8, ImageInfo->motorola_intel);
                /* If its bigger than 4 bytes, the dir entry contains an offset. */
@@ -2912,6 +2923,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
                efree(dump_data);
        }
 #endif
+
        if (section_index==SECTION_THUMBNAIL) {
                if (!ImageInfo->Thumbnail.data) {
                        switch(tag) {
diff --git a/ext/exif/tests/bug54002.phpt b/ext/exif/tests/bug54002.phpt
new file mode 100644 (file)
index 0000000..1999246
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+Bug #54002 (crash on crafted tag)
+--INI--
+memory_limit=-1
+--SKIPIF--
+<?php if (!extension_loaded('exif')) print 'skip exif extension not available';?>
+--FILE--
+<?php
+exif_read_data(__DIR__ . '/bug54002_1.jpeg');
+exif_read_data(__DIR__ . '/bug54002_2.jpeg');
+
+?>
+--EXPECTF--
+Warning: exif_read_data(bug54002_1.jpeg): Process tag(x0205=UndefinedTa): Illegal byte_count(%d) 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(%d) 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
diff --git a/ext/exif/tests/bug54002_1.jpeg b/ext/exif/tests/bug54002_1.jpeg
new file mode 100644 (file)
index 0000000..a622d6d
Binary files /dev/null and b/ext/exif/tests/bug54002_1.jpeg differ
diff --git a/ext/exif/tests/bug54002_2.jpeg b/ext/exif/tests/bug54002_2.jpeg
new file mode 100644 (file)
index 0000000..a622d6d
Binary files /dev/null and b/ext/exif/tests/bug54002_2.jpeg differ