1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
From: Markus Koschany <apo@debian.org>
Date: Thu, 8 Dec 2022 12:08:18 +0100
Subject: CVE-2021-3933
Bug-Debian: https://bugs.debian.org/1014828
Origin: https://github.com/AcademySoftwareFoundation/openexr/commit/5a0adf1aba7d41c6b94ba167c0c4308d2eecfd17
---
OpenEXR/IlmImf/ImfMisc.cpp | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/OpenEXR/IlmImf/ImfMisc.cpp b/OpenEXR/IlmImf/ImfMisc.cpp
index d2c8478..2f42961 100644
--- a/OpenEXR/IlmImf/ImfMisc.cpp
+++ b/OpenEXR/IlmImf/ImfMisc.cpp
@@ -161,7 +161,7 @@ bytesPerDeepLineTable (const Header &header,
{
const int ySampling = abs(c.channel().ySampling);
const int xSampling = abs(c.channel().xSampling);
- const int pixelSize = pixelTypeSize (c.channel().type);
+ const uint64_t pixelSize = pixelTypeSize (c.channel().type);
// Here we transform from the domain over all pixels into the domain
// of actual samples. We want to sample points in [minY, maxY] where
@@ -178,12 +178,22 @@ bytesPerDeepLineTable (const Header &header,
for (int y = sampleMinY; y <= sampleMaxY; y+=ySampling)
{
- int nBytes = 0;
+ uint64_t nBytes = 0;
for (int x = sampleMinX; x <= sampleMaxX; x += xSampling)
{
nBytes += pixelSize *
- sampleCount(base, xStride, yStride, x, y);
+ static_cast<uint64_t>(sampleCount(base, xStride, yStride, x, y));
}
+
+ //
+ // architectures where size_t is smaller than 64 bits may overflow
+ // (scanlines with more than 2^32 bytes are not currently supported so this should not occur with valid files)
+ //
+ if( static_cast<uint64_t>(bytesPerLine[y - dataWindow.min.y]) + nBytes > SIZE_MAX)
+ {
+ throw IEX_NAMESPACE::IoExc("Scanline size too large");
+ }
+
bytesPerLine[y - dataWindow.min.y] += nBytes;
}
}
@@ -191,8 +201,12 @@ bytesPerDeepLineTable (const Header &header,
size_t maxBytesPerLine = 0;
for (int y = minY; y <= maxY; ++y)
+ {
if (maxBytesPerLine < bytesPerLine[y - dataWindow.min.y])
+ {
maxBytesPerLine = bytesPerLine[y - dataWindow.min.y];
+ }
+ }
return maxBytesPerLine;
}
|