Skip to content

Fuzz exif thumbnail handling - #24722

Merged
ndossche merged 2 commits into
php:masterfrom
yumasansansan:fuzzer-exif-thumbnails
Oct 28, 2026
Merged

ndossche merged 2 commits into
php:masterfrom
yumasansansan:fuzzer-exif-thumbnails

Conversation

@yumasansansan

Copy link
Copy Markdown
Contributor

php-fuzz-exif calls exif_read_data($stream) with the default arguments. With $read_thumbnail = false, the thumbnail is never extracted (ImageInfo->read_thumbnail gates several code paths in ext/exif/exif.c), and exif_thumbnail() is not called at all.

The fuzzer now calls exif_read_data($stream, null, false, true) and exif_thumbnail($stream, $width, $height, $type). Passing $width/$height makes exif_thumbnail() call exif_scan_thumbnail().

Replaying the checked-in sapi/fuzzer/corpus/exif (no fuzzing):

Function Before (edges) After (edges)
zif_exif_thumbnail not reached 13/45
exif_thumbnail_build not reached 29/73
exif_thumbnail_extract not reached 3/11
exif_thumbnail_in_file not reached 2/4
exif_scan_thumbnail 2/48 8/48

The input format is unchanged, existing corpora stay valid.

exif_read_data() only reads the thumbnail if $read_thumbnail is true,
and exif_thumbnail() only scans the thumbnail for its dimensions if they
are requested, so the exif fuzzer never reached this code.

@ndossche ndossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this, see my (minor) suggestion please

Comment thread sapi/fuzzer/fuzzer-exif.c Outdated
@@ -47,7 +47,23 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
php_stream_write(stream, (const char *) Data, Size);
php_stream_to_zval(stream, &stream_zv);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small cleanup you can do:

Suggested change
php_stream_to_zval(stream, &stream_zv);
php_stream_to_zval(stream, &args[0]);

And then get rid of stream_zv, and the ZVAL_COPY_VALUE(&args[0], &stream_zv); below

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, done.

@ndossche
ndossche merged commit 2295a35 into php:master Oct 28, 2026
18 checks passed
@ndossche

Copy link
Copy Markdown
Member

Merged, thank you for your contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants