CVE-2025-64783 AI-generated analysis
platform/external/dng_sdk, DNG/TIFF raw image parsing and rendering library (source/dng_*.cpp)
Google fixed this High-severity information disclosure in external/dng_sdk by updating the whole bundled Adobe DNG SDK to version 1.7.1 build 2410 (61 files, about 2700 insertions) rather than with an isolated point fix.
Root cause
The material does not identify the specific defect. The fix commit "Update to DNG SDK 1.7.1 2410" (Bug 465781139) replaces the prior SDK snapshot with Adobe's 1.7.1/2410 release. Hardening visible in the shown portion of the diff: - source/dng_jxl.cpp dng_jxl_io_buffer::ReadChunk now throws ThrowEndOfFile when no bytes remain and limits each read to the remaining stream length. - source/dng_ifd.cpp dng_ifd::ParseTag gains a new tcGainMapMetadata_ISO_21496_1 handler with a 4 MiB tag-count cap. - source/dng_gain_map.cpp dng_opcode_GainMap::ProcessArea rewrites its row and column stepping as count-based loops, with rowPitch and colPitch clamped to the overlap size. - source/dng_fingerprint.h makes dng_fingerprint::data private behind Data()/MutableData(). The material does not show which of these changes (or which of the roughly 3000 unshown diff lines) corresponds to the CVE.
How the fix works
- Single commit per branch (Change-Id Ia850e7c3a3ab1b35dd619cc78159663df3b2b2c8, cherry-picked from internal commits 403d0a45 and defc6b20). It replaces the SDK sources with 1.7.1 build 2410; source/dng_flags.h now defines kDNGSDK_VersionString "1.7.1" and kDNGSDK_BuildVersion 2410.
- source/dng_jxl.cpp dng_jxl_io_buffer::ReadChunk computes bytes_remaining_in_stream from stream.Length() - stream.Position(). It throws ThrowEndOfFile("dng_jxl_io_buffer") when that is zero and limits next_read_size to min(fChunkSize, remaining). When fIndex + next_read_size would exceed fMaxBufferSize, it memmoves the unconsumed bytes to the buffer start and resets fIndex. dng_jxl.cpp also gains new streaming adapters: jxl_data_writer, jxl_data_writer2 (with a 1 GiB kMaxSize guard) and jxl_image_chunk_reader (which uses SafeUint32Mult for buffer sizing).
- source/dng_ifd.cpp dng_ifd::ParseTag has a new tcGainMapMetadata_ISO_21496_1 case. It checks tagType == ttUndefined, rejects tagCount > 4*1024*1024 with ThrowBadFormat, allocates tagCount bytes via host.Allocate and reads them with stream.Get. dng_ifd::IsValidDNG now accepts sfPreviewGainMap alongside sfGainMap. dng_ifd::IsBaselineJPEG now also returns true for ccJPEG + piRGB with 3 or 4 samples.
- source/dng_gain_map.cpp dng_opcode_GainMap::ProcessArea clamps rowPitch and colPitch to overlap.H() and overlap.W(). rows and cols become ceiling-divided counts, and the loops iterate rowIdx/colIdx, advancing row and col by the clamped pitch. This replaces the previous pitch-stepped loops (row < overlap.b with row += fAreaSpec.RowPitch(), and col < cols with col += colPitch).
- source/dng_fingerprint.h and .cpp: - dng_fingerprint::data becomes private (friends: dng_fingerprint_less_than and dng_md5_printer), and an explicit copy constructor and copy assignment are added. - dng_md5_printer::Process(const void*, uint32) is renamed ProcessPtr. New overloads Process(const dng_fingerprint&) and Process(const dng_string&) are added, plus Process_bool and Process_size. - The dng_md5_printer constructor becomes protected. New concrete classes are dng_md5_printer_le_stream (always little-endian) and dng_md5_direct_printer. - Digest call sites across the SDK are converted to the typed APIs and to Put_* calls.
- source/dng_exceptions.h and .cpp: dng_exception now derives from std::exception and provides a what() string. With qDNGVerboseExceptions (default 1 in dng_flags.h), the message and sub_message are carried into the exception. DNG_NO_RETURN uses [[noreturn]] under C++11.
- source/dng_abort_sniffer.cpp: the dng_sniffer_task destructor is moved out of line, made virtual, and wraps fSniffer->EndTask() in try/catch(...).
- source/dng_info.cpp: the dng_info constructor initializes fTIFFBlockOriginalOffset to 0 instead of kDNGStreamInvalidOffset. ParseDNGPrivateData adds a RICOH branch that calls ParseMakerNoteIFD on the private block.
- source/dng_image_writer.cpp and .h: WriteTIFF, WriteTIFFWithProfile, WriteDNG and WriteDNGWithMetadata gain a gainMapMetadataBlock parameter and gainMapAltProfileData/gainMapAltProfileSize parameters. The TIFF gain map is written only when both the image and the metadata block are present. The PGTM duplication logic now uses profile_tag_set::ProfileDidWritePGTMToMainIFD.
Completeness
- The fix is a version bump, so it carries every upstream change between the previous snapshot and 1.7.1/2410, not just the CVE fix. The material does not allow judging the specific vulnerable path.
- The shown diff is truncated (3031 further lines not displayed). This includes the full changes to dng_stream.cpp (+189), dng_pixel_buffer.cpp (+60), dng_linearization_info.cpp (+89), dng_misc_opcodes.cpp (128 changed lines), dng_negative.cpp (96) and dng_read_image.cpp (23), so parser-side bounds changes in those files cannot be assessed here.
- The r29 context still shows an Android GOOGLE MODIFICATION block (the plane-clamping loop in dng_misc_opcodes.cpp dng_opcode_MapTable::ProcessArea).
- The r29 context for Android 14 shows kDNGSDK_BuildVersion 2502, so the branch was later moved beyond build 2410. This commit alone brings it to 2410.
Behavior changes
- dng_exception is now a std::exception subclass. Throw_dng_error includes message/sub_message in what() when qDNGVerboseExceptions is 1 (its default in dng_flags.h).
- JPEG XL input: dng_jxl_io_buffer::ReadChunk throws an end-of-file error when no bytes remain in the stream.
- The new tag tcGainMapMetadata_ISO_21496_1 is parsed. A tagCount above 4 MiB raises a bad-format error.
- NewSubFileType sfPreviewGainMap is now accepted as a valid gain map IFD. IsBaselineJPEG now treats JPEG RGB with 3 or 4 samples per pixel as baseline.
- DNGPrivateData blocks with a RICOH prefix are now parsed as Pentax maker notes.
- Several fingerprint and digest computations now use dng_md5_printer_le_stream and typed Put_* calls.
- dng_info::fTIFFBlockOriginalOffset is now initialized to 0 rather than kDNGStreamInvalidOffset.
- API changes: - dng_fingerprint::data is private (use Data()/MutableData()). - dng_md5_printer::Process(void*, len) is renamed ProcessPtr. - dng_md5_printer can no longer be instantiated directly. - WriteTIFF/WriteDNG signatures gain gain-map metadata parameters.
Per major
- Android 14: Same fix: platform/external/dng_sdk d0bfe8eeee73 (Update to DNG SDK 1.7.1 2410) in android-security-14.0.0_r25. At android-security-14.0.0_r29 the patched region is fully present (8/8 lines), and the tree has since moved to build 2502.
- Android 15: Same fix: 45da10961287 in android-security-15.0.0_r13. The shown portion of the diff is identical to Android 14. Present at android-security-15.0.0_r17 (8/8).
- Android 16: Same fix: 6b5cf2a88ebd in android-security-16.0.0_r4. Present at android-security-16.0.0_r8 (8/8).
- Android 17: Not listed by the bulletin (not affected per the bulletin). The patched code is present at android-security-17.0.0_r1 (8/8).
Unknowns
- Which specific code change in the SDK update corresponds to CVE-2025-64783, and the exact trigger (tag, compression type or opcode) for the information disclosure.
- The pre-fix body of dng_jxl_io_buffer::ReadChunk, which the diff does not show.
- Content of the roughly 3000 truncated diff lines, including the changes to dng_stream.cpp, dng_pixel_buffer.cpp, dng_linearization_info.cpp and dng_misc_opcodes.cpp.
- Why Android 17 is not listed as affected while its tree contains the same code.