Commit 8bfed9a9 for libheif
commit 8bfed9a9ed008e4ef28abc736284a90d3cba754f
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Tue Aug 25 22:51:53 2026 +0200
unci: fix integer overflow in no-icef tile range check (GHSA-hh47-fhqr-cj2r)
The no-icef full-item generic-compression branch of
unc_decoder::get_compressed_image_data_uncompressed() still used the
overflow-prone addition-form range check
range_start_offset + range_size > data->size()
A crafted uncompressed tile grid can make range_start_offset + range_size
wrap to zero in uint64_t, bypassing the check and reaching a memcpy() with
an out-of-range source pointer and length (out-of-bounds read, SIGSEGV via
heif_image_handle_decode_image_tile()).
Use the same subtraction-form guard already applied to the icef sibling
branch in 089a809b. This is also the branch actually exercised by the
GHSA-73p7-m7gg-w2jv / CVE-2026-62292 proof of concept (icef absent,
compressed_unit_type = full_item); the 089a809b fix had guarded the icef
branch instead, so v1.23.1 remained vulnerable to the original PoC.
diff --git a/libheif/codecs/uncompressed/unc_decoder.cc b/libheif/codecs/uncompressed/unc_decoder.cc
index 9aeba61b..48cae1f8 100644
--- a/libheif/codecs/uncompressed/unc_decoder.cc
+++ b/libheif/codecs/uncompressed/unc_decoder.cc
@@ -238,7 +238,12 @@ const Error unc_decoder::get_compressed_image_data_uncompressed(const DataExtent
*data = std::move(*dataResult);
- if (range_start_offset + range_size > data->size()) {
+ // Use subtraction form to avoid a uint64_t wrap in 'range_start_offset + range_size'.
+ // A crafted tiling can make the requested tile range wrap to zero, passing the
+ // addition-form check and leading to an out-of-bounds read in the memcpy() below
+ // (GHSA-hh47-fhqr-cj2r; same root cause as the icef sibling branch above, GHSA-73p7-m7gg-w2jv).
+ if (range_start_offset > data->size() ||
+ range_size > data->size() - range_start_offset) {
return {
heif_error_Invalid_input,
heif_suberror_Unspecified,