From 6a0da6dc2e53875ee98edfa4ec89a76585897a78 Mon Sep 17 00:00:00 2001 From: Oblivionsage Date: Tue, 2 Dec 2025 18:57:05 +0100 Subject: [PATCH] Fix GH-20631: Integer underflow in exif HEIF parsing When pos.size is less than 2, the subtraction pos.size - 2 causes an unsigned integer underflow, resulting in a ~4GB allocation attempt. Add minimum size check (pos.size >= 2) to prevent the underflow. Closes GH-20630. --- NEWS | 3 +++ ext/exif/exif.c | 2 +- ext/exif/tests/heic_iloc_underflow.phpt | 19 +++++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 ext/exif/tests/heic_iloc_underflow.phpt diff --git a/NEWS b/NEWS index 7863b56edaa..7dc690d6758 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.5.2 +- EXIF: + . Fixed bug GH-20631 (Integer underflow in exif HEIF parsing + when pos.size < 2). (Oblivionsage) 18 Dec 2025, PHP 8.5.1 diff --git a/ext/exif/exif.c b/ext/exif/exif.c index d0c16413062..6ed86c88e56 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -4421,7 +4421,7 @@ static bool exif_scan_HEIF_header(image_info_type *ImageInfo, unsigned char *buf if (exif_read_from_stream_file_looped(ImageInfo->infile, (char*)(data + remain), limit - remain) == limit - remain) { exif_isobmff_parse_meta(data, data + limit, &pos); } - if ((pos.size) && + if ((pos.size >= 2) && (pos.size < ImageInfo->FileSize) && (ImageInfo->FileSize - pos.size >= pos.offset) && (php_stream_seek(ImageInfo->infile, pos.offset + 2, SEEK_SET) >= 0)) { diff --git a/ext/exif/tests/heic_iloc_underflow.phpt b/ext/exif/tests/heic_iloc_underflow.phpt new file mode 100644 index 00000000000..9dd1878b60d --- /dev/null +++ b/ext/exif/tests/heic_iloc_underflow.phpt @@ -0,0 +1,19 @@ +--TEST-- +HEIC iloc extent_length underflow +--EXTENSIONS-- +exif +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Warning: exif_read_data(heic_iloc_underflow.heic): Invalid HEIF file in %s on line %d +bool(false)