From e5324a2484ec0782a76daca7dd5e1a5ac232b3d8 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 9 Oct 2019 15:07:51 +0200 Subject: [PATCH] Limit the amount of errors generated during exif parsing Emitting errors is fairly expensive, to the point that parsing a file with a huge number of invalid tags can take seconds. Generating ten thousand errors is unlikely to help anybody, but constitutes a potential DOS vector. --- ext/exif/exif.c | 16 +++++++++++- ext/exif/tests/bug76557.phpt | 48 +----------------------------------- ext/exif/tests/bug77753.phpt | 8 ++---- 3 files changed, 18 insertions(+), 54 deletions(-) diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 88230a8296..8152b69830 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -1939,16 +1939,29 @@ typedef struct { int read_thumbnail; int read_all; int ifd_nesting_level; + int num_errors; /* internal */ file_section_list file; } image_info_type; /* }}} */ +#define EXIF_MAX_ERRORS 10 + /* {{{ exif_error_docref */ -static void exif_error_docref(const char *docref EXIFERR_DC, const image_info_type *ImageInfo, int type, const char *format, ...) +static void exif_error_docref(const char *docref EXIFERR_DC, image_info_type *ImageInfo, int type, const char *format, ...) { va_list args; + if (ImageInfo) { + if (++ImageInfo->num_errors > EXIF_MAX_ERRORS) { + if (ImageInfo->num_errors == EXIF_MAX_ERRORS+1) { + php_error_docref(docref, type, + "Further exif parsing errors have been suppressed"); + } + return; + } + } + va_start(args, format); #ifdef EXIF_DEBUG { @@ -4337,6 +4350,7 @@ static int exif_read_from_impl(image_info_type *ImageInfo, php_stream *stream, i ImageInfo->ifd_nesting_level = 0; + ImageInfo->num_errors = 0; /* Scan the headers */ ret = exif_scan_FILE_header(ImageInfo); diff --git a/ext/exif/tests/bug76557.phpt b/ext/exif/tests/bug76557.phpt index 9e19fff2a0..03a67ac940 100644 --- a/ext/exif/tests/bug76557.phpt +++ b/ext/exif/tests/bug76557.phpt @@ -28,52 +28,6 @@ Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal f Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d -Warning: exif_read_data(bug76557.jpg): Process tag(x8769=Exif_IFD_Po): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x927C=MakerNote ): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal pointer offset(%s) in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): File structure corrupted in %sbug76557.php on line %d - -Warning: exif_read_data(bug76557.jpg): Invalid JPEG file in %sbug76557.php on line %d +Warning: exif_read_data(): Further exif parsing errors have been suppressed in %s on line %d bool(false) DONE diff --git a/ext/exif/tests/bug77753.phpt b/ext/exif/tests/bug77753.phpt index d987a5cf46..8071603a04 100644 --- a/ext/exif/tests/bug77753.phpt +++ b/ext/exif/tests/bug77753.phpt @@ -4,13 +4,9 @@ Bug #77753 (Heap-buffer-overflow in php_ifd_get32s) --FILE-- DONE --EXPECTF-- -%A -Warning: exif_read_data(bug77753.tiff): Illegal IFD size: 0x006A > 0x0065 in %sbug77753.php on line %d - -Warning: exif_read_data(bug77753.tiff): Invalid TIFF file in %sbug77753.php on line %d bool(false) -DONE \ No newline at end of file +DONE -- 2.40.0