mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
Fix out-of-bounds read in exif tag reading
This issue was recently introduced in c739023a50
,
when the restriction that components>0 has been relaxed. We now need
to make sure that any tags that expect at least one component check
that this is the case.
This commit is contained in:
parent
003c13d7bc
commit
0fa13028cb
@ -3256,6 +3256,14 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
|
|||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
#define REQUIRE_NON_EMPTY() do { \
|
||||||
|
if (byte_count == 0) { \
|
||||||
|
exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Process tag(x%04X=%s): Cannot be empty", tag, exif_get_tagname(tag, tagname, -12, tag_table)); \
|
||||||
|
return FALSE; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/* {{{ exif_process_IFD_TAG
|
/* {{{ exif_process_IFD_TAG
|
||||||
* Process one of the nested IFDs directories. */
|
* Process one of the nested IFDs directories. */
|
||||||
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)
|
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)
|
||||||
@ -3373,8 +3381,12 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* NB: The following code may not assume that there is at least one component!
|
||||||
|
* byte_count may be zero! */
|
||||||
|
|
||||||
if (section_index==SECTION_THUMBNAIL) {
|
if (section_index==SECTION_THUMBNAIL) {
|
||||||
if (!ImageInfo->Thumbnail.data) {
|
if (!ImageInfo->Thumbnail.data) {
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
switch(tag) {
|
switch(tag) {
|
||||||
case TAG_IMAGEWIDTH:
|
case TAG_IMAGEWIDTH:
|
||||||
case TAG_COMP_IMAGE_WIDTH:
|
case TAG_COMP_IMAGE_WIDTH:
|
||||||
@ -3457,6 +3469,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||||||
case TAG_FNUMBER:
|
case TAG_FNUMBER:
|
||||||
/* Simplest way of expressing aperture, so I trust it the most.
|
/* Simplest way of expressing aperture, so I trust it the most.
|
||||||
(overwrite previously computed value if there is one) */
|
(overwrite previously computed value if there is one) */
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
ImageInfo->ApertureFNumber = (float)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
|
ImageInfo->ApertureFNumber = (float)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3465,6 +3478,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||||||
/* More relevant info always comes earlier, so only use this field if we don't
|
/* More relevant info always comes earlier, so only use this field if we don't
|
||||||
have appropriate aperture information yet. */
|
have appropriate aperture information yet. */
|
||||||
if (ImageInfo->ApertureFNumber == 0) {
|
if (ImageInfo->ApertureFNumber == 0) {
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
ImageInfo->ApertureFNumber
|
ImageInfo->ApertureFNumber
|
||||||
= (float)exp(exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel)*log(2)*0.5);
|
= (float)exp(exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel)*log(2)*0.5);
|
||||||
}
|
}
|
||||||
@ -3476,6 +3490,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||||||
SHUTTERSPEED comes after EXPOSURE TIME
|
SHUTTERSPEED comes after EXPOSURE TIME
|
||||||
*/
|
*/
|
||||||
if (ImageInfo->ExposureTime == 0) {
|
if (ImageInfo->ExposureTime == 0) {
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
ImageInfo->ExposureTime
|
ImageInfo->ExposureTime
|
||||||
= (float)(1/exp(exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel)*log(2)));
|
= (float)(1/exp(exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel)*log(2)));
|
||||||
}
|
}
|
||||||
@ -3485,20 +3500,24 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_COMP_IMAGE_WIDTH:
|
case TAG_COMP_IMAGE_WIDTH:
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
ImageInfo->ExifImageWidth = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel);
|
ImageInfo->ExifImageWidth = exif_convert_any_to_int(value_ptr, exif_rewrite_tag_format_to_unsigned(format), ImageInfo->motorola_intel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_FOCALPLANE_X_RES:
|
case TAG_FOCALPLANE_X_RES:
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
ImageInfo->FocalplaneXRes = exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
|
ImageInfo->FocalplaneXRes = exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_SUBJECT_DISTANCE:
|
case TAG_SUBJECT_DISTANCE:
|
||||||
/* Inidcates the distacne the autofocus camera is focused to.
|
/* Inidcates the distacne the autofocus camera is focused to.
|
||||||
Tends to be less accurate as distance increases. */
|
Tends to be less accurate as distance increases. */
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
ImageInfo->Distance = (float)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
|
ImageInfo->Distance = (float)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_FOCALPLANE_RESOLUTION_UNIT:
|
case TAG_FOCALPLANE_RESOLUTION_UNIT:
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
switch((int)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel)) {
|
switch((int)exif_convert_any_format(value_ptr, format, ImageInfo->motorola_intel)) {
|
||||||
case 1: ImageInfo->FocalplaneUnits = 25.4; break; /* inch */
|
case 1: ImageInfo->FocalplaneUnits = 25.4; break; /* inch */
|
||||||
case 2:
|
case 2:
|
||||||
@ -3541,6 +3560,7 @@ static int exif_process_IFD_TAG(image_info_type *ImageInfo, char *dir_entry, cha
|
|||||||
case TAG_GPS_IFD_POINTER:
|
case TAG_GPS_IFD_POINTER:
|
||||||
case TAG_INTEROP_IFD_POINTER:
|
case TAG_INTEROP_IFD_POINTER:
|
||||||
if (ReadNextIFD) {
|
if (ReadNextIFD) {
|
||||||
|
REQUIRE_NON_EMPTY();
|
||||||
char *Subdir_start;
|
char *Subdir_start;
|
||||||
int sub_section_index = 0;
|
int sub_section_index = 0;
|
||||||
switch(tag) {
|
switch(tag) {
|
||||||
|
@ -8,5 +8,7 @@ Bug #73737 (Crash when parsing a tag format)
|
|||||||
var_dump($exif);
|
var_dump($exif);
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
|
Warning: exif_thumbnail(bug73737.tiff): Process tag(x0100=ImageWidth ): Cannot be empty in %s on line %d
|
||||||
|
|
||||||
Warning: exif_thumbnail(bug73737.tiff): Error in TIFF: filesize(x0030) less than start of IFD dir(x10102) in %s line %d
|
Warning: exif_thumbnail(bug73737.tiff): Error in TIFF: filesize(x0030) less than start of IFD dir(x10102) in %s line %d
|
||||||
bool(false)
|
bool(false)
|
||||||
|
BIN
ext/exif/tests/tag_with_illegal_zero_components.jpeg
Normal file
BIN
ext/exif/tests/tag_with_illegal_zero_components.jpeg
Normal file
Binary file not shown.
15
ext/exif/tests/tag_with_illegal_zero_components.phpt
Normal file
15
ext/exif/tests/tag_with_illegal_zero_components.phpt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
--TEST--
|
||||||
|
OSS-Fuzz #17163: Out-of-bounds read due to tag with zero components
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
var_dump(exif_read_data(__DIR__ . '/tag_with_illegal_zero_components.jpeg'));
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Warning: exif_read_data(tag_with_illegal_zero_components.jpeg): Process tag(x0202=JPEGInterch): Cannot be empty in %s on line %d
|
||||||
|
|
||||||
|
Warning: exif_read_data(tag_with_illegal_zero_components.jpeg): File structure corrupted in %s on line %d
|
||||||
|
|
||||||
|
Warning: exif_read_data(tag_with_illegal_zero_components.jpeg): Invalid JPEG file in %s on line %d
|
||||||
|
bool(false)
|
Loading…
Reference in New Issue
Block a user