Repository navigation
Fuzz/xmp merge coverage - #479
Open
DichenZhang1 wants to merge 11 commits into
Open
DichenZhang1 wants to merge 11 commits into
DichenZhang1 wants to merge 11 commits into
Conversation
- Expose uhdr_enc_set_xmp_data and uhdr_dec_get_xmp in public C API - Support passing custom XMP metadata into encodeJPEGR and appendGainMap - In ISO metadata mode, pass through user/base XMP packet directly - In XMP metadata mode, merge Ultra HDR container directory into user/base XMP RDF - Automatically extract and preserve base JPEG XMP in API-2/3/4 encoding workflows - Wire -X <xmp_file> and probe XMP display into ultrahdr_app CLI - Add unit tests verifying XMP encoding, decoding, and preservation across API-0 and API-2
- Support encoding and decoding Extended XMP metadata (> 64 KB) in JPEG - Compute 128-bit MD5 GUID and inject xmpNote:HasExtendedXMP into Standard XMP - Chunk serialized Extended XMP payload across multiple http://ns.adobe.com/xmp/extension/\0 APP1 segments - Reassemble Extended XMP chunks during JPEG header parsing and expose reconstructed buffer - Calculate dynamic encoder output buffer allowance based on total XMP size and chunk count - Add unit tests validating multi-segment Extended XMP encoding, decoding, and bit-for-bit roundtrip integrity
The primary image XMP packet is untrusted input. When a gain map is
appended to an already compressed base image, jpegr.cpp inherits that
image's APP1 packet verbatim:
if (pXmp == nullptr && decoder.getXMPSize() > 0) {
xmp_from_jpg.data = decoder.getXMPPtr();
pXmp = &xmp_from_jpg;
}
and hands it to generateXmpForPrimaryImage(), which now parses the
packet, resolves namespace prefixes, locates and rewrites the encoder
owned gain map description by byte offset, and reserializes the result.
That is a few hundred lines of hand rolled XML span arithmetic reachable
from attacker controlled bytes, and none of the existing fuzz targets
reach it: ultrahdr_enc_fuzzer only ever feeds the encoder base images it
generated itself, whose XMP is well formed by construction.
Add a dedicated target that drives:
* generateXmpForPrimaryImage() with an arbitrary user packet (and, for
contrast, with no user packet at all),
* getMetadataFromXMP() on the merged result, so the packet we emit has
to survive our own reader,
* getMetadataFromXMP() on the raw untrusted packet.
Wired into CMake, ossfuzz.sh and Android.bp alongside the existing
enc/dec/legacy targets. No new build options are required:
generateXmpForPrimaryImage() is compiled unconditionally, so the target
builds in the default OSS-Fuzz configuration.
Smoke tested locally against a stub FuzzedDataProvider (this host has no
clang) over well formed, truncated, fragmented and NUL bearing packets:
no crashes, and the target compiles clean under -Wall -Wextra -Werror.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fuzzer: add ultrahdr_xmp_fuzzer for the primary image XMP merge
The primary image XMP packet is untrusted input. When a gain map is
appended to an already compressed base image, jpegr.cpp inherits that
image's APP1 packet verbatim:
and hands it to generateXmpForPrimaryImage(), which now parses the
packet, resolves namespace prefixes, locates and rewrites the encoder
owned gain map description by byte offset, and reserializes the result.
That is a few hundred lines of hand rolled XML span arithmetic reachable
from attacker controlled bytes, and none of the existing fuzz targets
reach it: ultrahdr_enc_fuzzer only ever feeds the encoder base images it
generated itself, whose XMP is well formed by construction.
Add a dedicated target that drives:
contrast, with no user packet at all),
to survive our own reader,
Wired into CMake, ossfuzz.sh and Android.bp alongside the existing
enc/dec/legacy targets. No new build options are required:
generateXmpForPrimaryImage() is compiled unconditionally, so the target
builds in the default OSS-Fuzz configuration.
Smoke tested locally against a stub FuzzedDataProvider (this host has no
clang) over well formed, truncated, fragmented and NUL bearing packets:
no crashes, and the target compiles clean under -Wall -Wextra -Werror.