mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-10-15 18:27:12 +00:00
libheif: patch CVE-2026-62289
Backport commit identified by Debian[1] Details: https://nvd.nist.gov/vuln/detail/cve-2026-62289 [1]https://security-tracker.debian.org/tracker/CVE-2026-62289 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
1 parent
c27765e057
commit
8dcbf99224
2 files changed
+190
No files matched your search
@@ -0,0 +1,189 @@
|
||||
From 49e188ca7a6a81fd1c7d5e76254308c82cbcb5c3 Mon Sep 17 00:00:00 2001
|
||||
From: Dirk Farin <dirk.farin@gmail.com>
|
||||
Date: Thu, 25 Jun 2026 19:58:57 +0200
|
||||
Subject: [PATCH] Fix clap transform double-application in image tiling
|
||||
(GHSA-jc8f-p23p-5hjg)
|
||||
|
||||
The base ImageItem::get_heif_image_tiling() returned the already
|
||||
transformed m_width/m_height, but process_image_transformations_on_tiling()
|
||||
applies the transformative properties (irot, imir, clap) itself. This
|
||||
applied every transform twice. For a clap that rounds the image down to
|
||||
zero, the second application passed 0 into Box_clap::left_rounded(), where
|
||||
`image_width - 1U` underflowed to UINT32_MAX and overflowed the Fraction
|
||||
constructor (assert abort in debug builds, corrupt crop in release builds).
|
||||
The grid, unc and tiled overrides already return coded dimensions, so the
|
||||
base class was the lone outlier.
|
||||
|
||||
Fixes, in three layers:
|
||||
|
||||
- image_item.cc: base get_heif_image_tiling() now reports coded (ispe)
|
||||
dimensions when available, matching the other overrides, so transforms
|
||||
are applied exactly once. This also fixes a silent irot/imir
|
||||
double-transform on the same path.
|
||||
- context.cc: reject a clap that rounds a dimension to zero or less at
|
||||
parse time, mirroring the existing ispe zero-size check.
|
||||
- box.cc: guard left_rounded()/top_rounded() against a zero image
|
||||
dimension as defense in depth.
|
||||
|
||||
Add tests/clap_zero_size.cc covering the hardened clap helpers.
|
||||
|
||||
(cherry picked from commit f01870c1d7323a3003796d58eba7fff502be994c)
|
||||
|
||||
CVE: CVE-2026-62289
|
||||
Upstream-Status: Backport [https://github.com/strukturag/libheif/commit/f01870c1d7323a3003796d58eba7fff502be994c]
|
||||
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
|
||||
---
|
||||
libheif/box.cc | 11 ++++++++
|
||||
libheif/context.cc | 12 +++++++--
|
||||
libheif/image-items/image_item.cc | 23 ++++++++++++++---
|
||||
tests/CMakeLists.txt | 1 +
|
||||
tests/clap_zero_size.cc | 42 +++++++++++++++++++++++++++++++
|
||||
5 files changed, 83 insertions(+), 6 deletions(-)
|
||||
create mode 100644 tests/clap_zero_size.cc
|
||||
|
||||
diff --git a/libheif/box.cc b/libheif/box.cc
|
||||
index 76ba0f0a..57912ab0 100644
|
||||
--- a/libheif/box.cc
|
||||
+++ b/libheif/box.cc
|
||||
@@ -3592,6 +3592,12 @@ int Box_clap::left_rounded(uint32_t image_width) const
|
||||
|
||||
// left = horizOff + (width-1)/2 - (clapWidth-1)/2
|
||||
|
||||
+ // Guard against image_width==0: `image_width - 1U` would underflow to
|
||||
+ // UINT32_MAX and overflow the Fraction (GHSA-jc8f-p23p-5hjg).
|
||||
+ if (image_width == 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
Fraction pcX = m_horizontal_offset + Fraction(image_width - 1U, 2U);
|
||||
Fraction left = pcX - (m_clean_aperture_width - 1) / 2;
|
||||
|
||||
@@ -3607,6 +3613,11 @@ int Box_clap::right_rounded(uint32_t image_width) const
|
||||
|
||||
int Box_clap::top_rounded(uint32_t image_height) const
|
||||
{
|
||||
+ // Guard against image_height==0 underflowing the Fraction (see left_rounded).
|
||||
+ if (image_height == 0) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
Fraction pcY = m_vertical_offset + Fraction(image_height - 1U, 2U);
|
||||
Fraction top = pcY - (m_clean_aperture_height - 1) / 2;
|
||||
|
||||
diff --git a/libheif/context.cc b/libheif/context.cc
|
||||
index a1bcc268..a3371207 100644
|
||||
--- a/libheif/context.cc
|
||||
+++ b/libheif/context.cc
|
||||
@@ -644,8 +644,16 @@ Error HeifContext::interpret_heif_file_images()
|
||||
for (const auto& prop : properties) {
|
||||
auto clap = std::dynamic_pointer_cast<Box_clap>(prop);
|
||||
if (clap) {
|
||||
- image->set_resolution(clap->get_width_rounded(),
|
||||
- clap->get_height_rounded());
|
||||
+ int clap_width = clap->get_width_rounded();
|
||||
+ int clap_height = clap->get_height_rounded();
|
||||
+ if (clap_width <= 0 || clap_height <= 0) {
|
||||
+ return {heif_error_Invalid_input,
|
||||
+ heif_suberror_Invalid_clean_aperture,
|
||||
+ "Clean aperture (clap) reduces image to zero size"};
|
||||
+ }
|
||||
+
|
||||
+ image->set_resolution(static_cast<uint32_t>(clap_width),
|
||||
+ static_cast<uint32_t>(clap_height));
|
||||
|
||||
if (image->has_intrinsic_matrix()) {
|
||||
image->get_intrinsic_matrix().apply_clap(clap.get(), image->get_width(), image->get_height());
|
||||
diff --git a/libheif/image-items/image_item.cc b/libheif/image-items/image_item.cc
|
||||
index e803107f..d05536e1 100644
|
||||
--- a/libheif/image-items/image_item.cc
|
||||
+++ b/libheif/image-items/image_item.cc
|
||||
@@ -967,10 +967,25 @@ heif_image_tiling ImageItem::get_heif_image_tiling() const
|
||||
tiling.num_columns = 1;
|
||||
tiling.num_rows = 1;
|
||||
|
||||
- tiling.tile_width = m_width;
|
||||
- tiling.tile_height = m_height;
|
||||
- tiling.image_width = m_width;
|
||||
- tiling.image_height = m_height;
|
||||
+ // Report the coded (pre-transformation) dimensions here. The caller applies
|
||||
+ // the transformative properties (irot, imir, clap) via
|
||||
+ // process_image_transformations_on_tiling(), so handing it the already
|
||||
+ // transformed m_width/m_height would apply them a second time. For a clap
|
||||
+ // that shrinks the image to zero this double application underflowed inside
|
||||
+ // Box_clap::left_rounded() (GHSA-jc8f-p23p-5hjg); for irot/imir it silently
|
||||
+ // produced wrong dimensions. The grid/unc/tiled overrides likewise report
|
||||
+ // coded dimensions.
|
||||
+ uint32_t coded_width = m_width;
|
||||
+ uint32_t coded_height = m_height;
|
||||
+ if (has_ispe_resolution()) {
|
||||
+ coded_width = get_ispe_width();
|
||||
+ coded_height = get_ispe_height();
|
||||
+ }
|
||||
+
|
||||
+ tiling.tile_width = coded_width;
|
||||
+ tiling.tile_height = coded_height;
|
||||
+ tiling.image_width = coded_width;
|
||||
+ tiling.image_height = coded_height;
|
||||
|
||||
tiling.top_offset = 0;
|
||||
tiling.left_offset = 0;
|
||||
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
|
||||
index d8fdfd8b..b52bc202 100644
|
||||
--- a/tests/CMakeLists.txt
|
||||
+++ b/tests/CMakeLists.txt
|
||||
@@ -38,6 +38,7 @@ if (WITH_REDUCED_VISIBILITY)
|
||||
else()
|
||||
add_libheif_test(bitstream_tests)
|
||||
add_libheif_test(box_equals)
|
||||
+ add_libheif_test(clap_zero_size)
|
||||
add_libheif_test(conversion)
|
||||
add_libheif_test(idat)
|
||||
add_libheif_test(jpeg2000)
|
||||
diff --git a/tests/clap_zero_size.cc b/tests/clap_zero_size.cc
|
||||
new file mode 100644
|
||||
index 00000000..eafc1258
|
||||
--- /dev/null
|
||||
+++ b/tests/clap_zero_size.cc
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ libheif clean aperture (clap) zero-size unit tests
|
||||
+
|
||||
+ MIT License
|
||||
+
|
||||
+ Copyright (c) 2026 Dirk Farin <dirk.farin@gmail.com>
|
||||
+
|
||||
+ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
+ of this software and associated documentation files (the "Software"), to deal
|
||||
+ in the Software without restriction, including without limitation the rights
|
||||
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
+ copies of the Software, and to permit persons to whom the Software is
|
||||
+ furnished to do so, subject to the following conditions:
|
||||
+
|
||||
+ The above copyright notice and this permission notice shall be included in all
|
||||
+ copies or substantial portions of the Software.
|
||||
+
|
||||
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
+ SOFTWARE.
|
||||
+*/
|
||||
+
|
||||
+#include "catch_amalgamated.hpp"
|
||||
+#include "box.h"
|
||||
+
|
||||
+// Regression test for GHSA-jc8f-p23p-5hjg: passing a zero image dimension to
|
||||
+// the clap rounding helpers used to underflow `image_width - 1U` to UINT32_MAX,
|
||||
+// which overflowed the Fraction constructor (assert abort in debug builds,
|
||||
+// corrupt crop in release builds). They must now return 0 without aborting.
|
||||
+TEST_CASE("clap rounding with zero image size") {
|
||||
+ std::shared_ptr<Box_clap> clap = std::make_shared<Box_clap>();
|
||||
+ clap->set(100, 200, 150, 250); // clap 100x200 inside a 150x250 image
|
||||
+
|
||||
+ REQUIRE(clap->left_rounded(0) == 0);
|
||||
+ REQUIRE(clap->right_rounded(0) == 99); // clapWidth - 1 + left(0)
|
||||
+ REQUIRE(clap->top_rounded(0) == 0);
|
||||
+ REQUIRE(clap->bottom_rounded(0) == 199); // clapHeight - 1 + top(0)
|
||||
+}
|
||||
@@ -14,6 +14,7 @@ SRC_URI = "git://github.com/strukturag/libheif.git;protocol=https;branch=master;
|
||||
file://CVE-2026-32741.patch \
|
||||
file://CVE-2026-41071-1.patch \
|
||||
file://CVE-2026-41071-2.patch \
|
||||
file://CVE-2026-62289.patch \
|
||||
"
|
||||
|
||||
SRCREV = "62f1b8c76ed4d8305071fdacbe74ef9717bacac5"
|
||||
|
||||
Reference in new issue
Block a user