Resolves: RHEL-182270 RHEL-182502 - fix CVE-2026-41142 and CVE-2026-42216

Signed-off-by: Josef Ridky <jridky@redhat.com>
This commit is contained in:
Josef Ridky 2026-06-28 14:25:37 +02:00
parent 1ab481c322
commit 71bb02eb29
3 changed files with 207 additions and 1 deletions

View File

@ -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 <Iex.h>
+#include <ImathBox.h>
+
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <string>
+
+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 <string>
+
+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 <Iex.h>
+#include <cstdint>
+#include <limits>
+
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<uint64_t> (_pixelsPerRow);
+ const uint64_t h64 = static_cast<uint64_t> (_pixelsPerColumn);
+ const uint64_t maxPixels =
+ static_cast<uint64_t> (std::numeric_limits<size_t>::max ());
+ if (w64 != 0 && h64 > maxPixels / w64)
+ {
+ throw ArgExc ("Image channel dimensions too large.");
+ }
+
+ _numPixels = static_cast<size_t> (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

View File

@ -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]));

View File

@ -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 <jridky@redhat.com> - 3.1.1-6
- fix CVE-2026-41142
- fix CVE-2026-42216
* Tue Apr 28 2026 Josef Ridky <jridky@redhat.com> - 3.1.1-5
- fix CVE-2026-34588