diff --git a/openexr-CVE-2026-41142.patch b/openexr-CVE-2026-41142.patch new file mode 100644 index 0000000..e751f67 --- /dev/null +++ b/openexr-CVE-2026-41142.patch @@ -0,0 +1,181 @@ +diff -urNp a/src/test/OpenEXRUtilTest/testImageChannel.cpp b/src/test/OpenEXRUtilTest/testImageChannel.cpp +--- a/src/test/OpenEXRUtilTest/testImageChannel.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/test/OpenEXRUtilTest/testImageChannel.cpp 2026-06-25 11:21:58.464289792 +0200 +@@ -0,0 +1,82 @@ ++// ++// SPDX-License-Identifier: BSD-3-Clause ++// Copyright (c) Contributors to the OpenEXR Project. ++// ++ ++#ifdef NDEBUG ++# undef NDEBUG ++#endif ++ ++#include "testImageChannel.h" ++ ++#include "ImfFlatImage.h" ++ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++using namespace OPENEXR_IMF_NAMESPACE; ++using namespace IMATH_NAMESPACE; ++using namespace IEX_NAMESPACE; ++using namespace std; ++ ++namespace ++{ ++ ++// ++// Sampling must be >= 1. ImageChannel::resize() rejects non-positive ++// sampling before any modulo or division (so zero cannot invoke undefined ++// behavior). Other invalid cases are still caught later in resize(). ++// ++ ++void ++expectArgExcOnInsert (const char* label, int xSampling, int ySampling) ++{ ++ FlatImage img (Box2i (V2i (0, 0), V2i (3, 3))); ++ ++ try ++ { ++ img.insertChannel ("bad", HALF, xSampling, ySampling, false); ++ cerr << "ERROR -- " << label << ": expected ArgExc, insert succeeded" ++ << endl; ++ assert (false); ++ } ++ catch (const ArgExc& e) ++ { ++ // Thrown at the start of ImageChannel::resize() so % and / never use ++ // a zero sampling rate (undefined behavior). ++ assert (strstr (e.what (), "at least 1") != nullptr); ++ } ++} ++ ++} // namespace ++ ++void ++testImageChannel (const string& tempDir) ++{ ++ (void) tempDir; ++ ++ try ++ { ++ cout << "Testing ImageChannel sampling constraints" << endl; ++ ++ expectArgExcOnInsert ("negative xSampling", -1, 1); ++ expectArgExcOnInsert ("negative ySampling", 1, -1); ++ expectArgExcOnInsert ("negative x and y sampling", -1, -1); ++ ++ expectArgExcOnInsert ("zero xSampling", 0, 1); ++ expectArgExcOnInsert ("zero ySampling", 1, 0); ++ expectArgExcOnInsert ("zero x and y sampling", 0, 0); ++ ++ cout << "ok\n" << endl; ++ } ++ catch (const std::exception& e) ++ { ++ cerr << "ERROR -- caught exception: " << e.what () << endl; ++ assert (false); ++ } ++} +diff -urNp a/src/test/OpenEXRUtilTest/testImageChannel.h b/src/test/OpenEXRUtilTest/testImageChannel.h +--- a/src/test/OpenEXRUtilTest/testImageChannel.h 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/test/OpenEXRUtilTest/testImageChannel.h 2026-06-25 11:22:42.531155111 +0200 +@@ -0,0 +1,8 @@ ++// ++// SPDX-License-Identifier: BSD-3-Clause ++// Copyright (c) Contributors to the OpenEXR Project. ++// ++ ++#include ++ ++void testImageChannel (const std::string& tempDir); +diff -urNp a/src/lib/OpenEXRUtil/ImfImageChannel.cpp b/src/lib/OpenEXRUtil/ImfImageChannel.cpp +--- a/src/lib/OpenEXRUtil/ImfImageChannel.cpp 2026-06-28 14:08:47.148671652 +0200 ++++ b/src/lib/OpenEXRUtil/ImfImageChannel.cpp 2026-06-28 14:21:22.566904315 +0200 +@@ -13,6 +13,9 @@ + #include "ImfImageLevel.h" + #include + ++#include ++#include ++ + using namespace IMATH_NAMESPACE; + using namespace IEX_NAMESPACE; + using namespace std; +@@ -54,6 +57,13 @@ ImageChannel::channel () const + void + ImageChannel::resize () + { ++ if (_xSampling < 1 || _ySampling < 1) ++ { ++ throw ArgExc ( ++ "The x and y sampling rates for an image channel must be at " ++ "least 1."); ++ } ++ + const Box2i& dataWindow = level().dataWindow(); + + if (dataWindow.min.x % _xSampling || dataWindow.min.y % _ySampling) +@@ -75,7 +85,17 @@ ImageChannel::resize () + + _pixelsPerRow = width / _xSampling; + _pixelsPerColumn = height / _ySampling; +- _numPixels = _pixelsPerRow * _pixelsPerColumn; ++ ++ const uint64_t w64 = static_cast (_pixelsPerRow); ++ const uint64_t h64 = static_cast (_pixelsPerColumn); ++ const uint64_t maxPixels = ++ static_cast (std::numeric_limits::max ()); ++ if (w64 != 0 && h64 > maxPixels / w64) ++ { ++ throw ArgExc ("Image channel dimensions too large."); ++ } ++ ++ _numPixels = static_cast (w64 * h64); + } + + +diff -urNp a/src/test/OpenEXRUtilTest/CMakeLists.txt b/src/test/OpenEXRUtilTest/CMakeLists.txt +--- a/src/test/OpenEXRUtilTest/CMakeLists.txt 2026-06-28 14:08:47.159128636 +0200 ++++ b/src/test/OpenEXRUtilTest/CMakeLists.txt 2026-06-28 14:22:35.504680842 +0200 +@@ -6,6 +6,8 @@ add_executable(OpenEXRUtilTest + testFlatImage.cpp + testDeepImage.cpp + testIO.cpp ++ testImageChannel.cpp ++ testImageChannel.h + ) + target_link_libraries(OpenEXRUtilTest OpenEXR::OpenEXRUtil) + set_target_properties(OpenEXRUtilTest PROPERTIES +@@ -26,4 +28,5 @@ define_openexr_util_tests( + testFlatImage + testDeepImage + testIO ++ testImageChannel + ) +diff -urNp a/src/test/OpenEXRUtilTest/main.cpp b/src/test/OpenEXRUtilTest/main.cpp +--- a/src/test/OpenEXRUtilTest/main.cpp 2026-06-28 14:08:47.159128636 +0200 ++++ b/src/test/OpenEXRUtilTest/main.cpp 2026-06-28 14:23:38.491487948 +0200 +@@ -11,6 +11,7 @@ + #include "OpenEXRConfigInternal.h" + + #include "testFlatImage.h" ++#include "testImageChannel.h" + #include "testDeepImage.h" + #include "testIO.h" + #include "tmpDir.h" +@@ -87,6 +88,7 @@ main (int argc, char *argv[]) + TEST (testFlatImage); + TEST (testDeepImage); + TEST (testIO); ++ TEST (testImageChannel); + // NB: If you add a test here, make sure to enumerate it in the + // CMakeLists.txt so it runs as part of the test suite + diff --git a/openexr-CVE-2026-42216.patch b/openexr-CVE-2026-42216.patch new file mode 100644 index 0000000..7e743f2 --- /dev/null +++ b/openexr-CVE-2026-42216.patch @@ -0,0 +1,17 @@ +diff -ruNp a/src/lib/OpenEXR/ImfIDManifest.cpp b/src/lib/OpenEXR/ImfIDManifest.cpp +--- a/src/lib/OpenEXR/ImfIDManifest.cpp 2026-06-25 11:37:35.541229769 +0200 ++++ b/src/lib/OpenEXR/ImfIDManifest.cpp 2026-06-25 11:39:22.576872688 +0200 +@@ -359,6 +359,13 @@ void IDManifest::init(const char* data, + // + // previous string had more than 255 characters? + // ++ const size_t minPrefixLen = ++ stringList[i - 1].size () > 255 ? size_t (2) : size_t (1); ++ if (stringList[i].size () < minPrefixLen) ++ { ++ throw IEX_NAMESPACE::InputExc ( ++ "IDManifest string too small for common prefix length"); ++ } + if(stringList[i-1].size()>255) + { + common = size_t( ((unsigned char) (stringList[i][0])) <<8 ) + size_t( (unsigned char) (stringList[i][1])); diff --git a/openexr.spec b/openexr.spec index e9284b6..750b03f 100644 --- a/openexr.spec +++ b/openexr.spec @@ -3,7 +3,7 @@ Name: openexr Version: 3.1.1 -Release: 5%{?dist} +Release: 6%{?dist} Summary: Provides the specification and reference implementation of the EXR file format License: BSD @@ -21,6 +21,10 @@ Patch1: openexr-CVE-2023-5481.patch Patch2: openexr-CVE-2026-27622.patch # Fix CVE 2026-34588 Patch3: openexr-CVE-2026-34588.patch +# Fix CVE-2026-41142 +Patch4: openexr-CVE-2026-41142.patch +# Fix CVE-2026-42216 +Patch5: openexr-CVE-2026-42216.patch Obsoletes: OpenEXR < 2.5.3 Provides: OpenEXR = %{version}-%{release} @@ -133,6 +137,10 @@ Summary: Development files for %{name} %changelog +* Fri Jun 26 2026 Josef Ridky - 3.1.1-6 +- fix CVE-2026-41142 +- fix CVE-2026-42216 + * Tue Apr 28 2026 Josef Ridky - 3.1.1-5 - fix CVE-2026-34588