Skip to content

Update vendored TinyEXIF to 8c22aff - #92

Merged
garbear merged 2 commits into
xbmc:Piersfrom
cinema-ONE:tinyexif-resync
Aug 30, 2026
Merged

Update vendored TinyEXIF to 8c22aff#92
garbear merged 2 commits into
xbmc:Piersfrom
cinema-ONE:tinyexif-resync

Conversation

@cinema-ONE

Copy link
Copy Markdown
Contributor

Updates the vendored TinyEXIF from 6e56015 (April 2021) to 8c22aff (August 2026).

Why

The pinned copy is missing two upstream memory-safety fixes — 841e2929 (heap buffer overflow in EntryParser::Fetch) and b6ea1b7b (integer overflow in the parseString bounds check).

The first is reachable here. Fuzzing the pinned copy under ASan segfaulted after 18 executions:

SEGV on unknown address 0x50c0ffff0b35
  #0 TinyEXIF::EntryParser::parse32                   TinyEXIF.cpp:283
  #1 TinyEXIF::EntryParser::parseRational             TinyEXIF.cpp:297
  #2 TinyEXIF::EntryParser::Fetch(double&, unsigned)  TinyEXIF.cpp:256
  #3 TinyEXIF::EXIFInfo::parseIFDExif                 TinyEXIF.cpp:615

That is exactly the function 841e2929 adds the missing offset + 8 > len check to. EXIF parsing runs whenever Kodi reads tags for a picture, so the input is attacker-controlled.

Worth noting for anyone re-checking this: upstream's published PoC samples do not reproduce it. The older parser rejects them as PARSE_CORRUPT_DATA before reaching that code, so replaying them says "not affected". The crash was found by fuzzing this pinned version specifically.

Verification

Old (6e56015) New (8c22aff)
The crash input SEGV parses cleanly
Fuzzing under ASan + UBSan crash at 18 executions 3,306,837 runs, 0 findings

Only parseFrom(), parseFromEXIFSegment(), ImageWidth, ImageHeight and Orientation are used here, all unchanged upstream. Builds clean.

CI will be red, and not because of this

This branch is off Piers, which does not compile against xbmc/xbmc master any more: ImageDecoder API 3.1.0 (xbmc/xbmc#29068) changed the Decode() signature, and CI here builds against master. #91 fixes that, and the two compose — I built this branch on top of it and both compile.

They are independent concerns and can merge in either order.


Written by my AI co-author (Claude Code); posted from my account.

@greptile-apps

greptile-apps Bot commented Aug 30, 2026

Copy link
Copy Markdown

Greptile Summary

Updates the vendored TinyEXIF snapshot and adopts its hardened EXIF parsing behavior.

  • Adds overflow-safe bounds checks for attacker-controlled EXIF offsets, counts, and strings.
  • Expands TinyEXIF field-presence, XMP, panorama, motion-photo, and distortion metadata support.
  • Corrects the length passed when parsing HEIF EXIF metadata after its four-byte prefix.
  • Refreshes the vendored version and licensing documentation.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
lib/TinyEXIF/TinyEXIF.cpp Updates the vendored parser with bounds-safe EXIF traversal and expanded metadata handling; no eligible follow-up finding was established.
lib/TinyEXIF/TinyEXIF.h Adds the updated TinyEXIF API, metadata structures, and field-presence interface.
src/HeifPicture.cpp Prevents metadata-length underflow and passes the remaining buffer length after skipping the HEIF EXIF prefix.
lib/TinyEXIF/README.md Documents the updated field-presence API and current licensing.
lib/kodi-TinyEXIF-note.txt Records the new vendored TinyEXIF revision.

Reviews (2): Last reviewed commit: "Do not read past the end of the EXIF met..." | Re-trigger Greptile

@garbear

garbear commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Jenkins not happy? Needs a rebase maybe?

cinema-ONE and others added 2 commits August 30, 2026 13:34
The copy here was pinned at 6e56015 (April 2021) and is missing two upstream
memory-safety fixes: 841e2929, a heap buffer overflow in EntryParser::Fetch,
and b6ea1b7b, an integer overflow in the parseString bounds check.

The first is reachable. Fuzzing the pinned copy under ASan segfaulted after
18 executions:

  EntryParser::parse32                   TinyEXIF.cpp:283
  EntryParser::parseRational             TinyEXIF.cpp:297
  EntryParser::Fetch(double&, unsigned)  TinyEXIF.cpp:256
  EXIFInfo::parseIFDExif                 TinyEXIF.cpp:615

which is exactly the function 841e2929 adds a bounds check to. EXIF parsing
runs whenever Kodi reads tags for a picture, so the input is attacker
controlled.

The upstream proof-of-concept samples do not reproduce it - the older parser
rejects them as corrupt before reaching that code - so this was found by
fuzzing the pinned version rather than by replaying published cases.

After the update that input parses cleanly and 3.3M fuzz executions found
nothing. Only parseFrom(), parseFromEXIFSegment(), ImageWidth, ImageHeight
and Orientation are used here, all unchanged upstream.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The buffer was advanced by type.length() but the full metadata.size() was
still passed as the length, so the parser could read that many bytes beyond
the end of the vector. A block shorter than the type string underflowed the
subtraction that should have been there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@cinema-ONE

Copy link
Copy Markdown
Contributor Author

Rebased — you were right. My earlier "the red clears once the API PRs merge" was wrong: this branch was still based on the pre-merge Piers, so it carried the old Decode signature and CI kept failing even after that landed. MERGEABLE was true but misleading — no textual conflict, just a stale base.

Now on current Piers and builds clean against the merged API. CI re-running.


Written by my AI co-author (Claude Code); posted from my account.

@garbear
garbear merged commit 026c802 into xbmc:Piers Aug 30, 2026
8 checks passed
@garbear

garbear commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Thanks! I'll handle releases when I get a chance.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants