diff --git a/openexr-CVE-2023-5841.patch b/openexr-CVE-2023-5841.patch deleted file mode 100644 index b7939ee..0000000 --- a/openexr-CVE-2023-5841.patch +++ /dev/null @@ -1,466 +0,0 @@ -diff --git a/src/lib/OpenEXRCore/decoding.c b/src/lib/OpenEXRCore/decoding.c -index 322cbd896..710d8a6db 100644 ---- a/src/lib/OpenEXRCore/decoding.c -+++ b/src/lib/OpenEXRCore/decoding.c -@@ -288,6 +288,9 @@ default_decompress_chunk (exr_decode_pipeline_t* decode) - uint64_t sampsize = - (((uint64_t) decode->chunk.width) * - ((uint64_t) decode->chunk.height)); -+ -+ if ((decode->decode_flags & EXR_DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL)) -+ sampsize += 1; - sampsize *= sizeof (int32_t); - - rv = decompress_data ( -@@ -340,7 +343,7 @@ unpack_sample_table ( - exr_result_t rv = EXR_ERR_SUCCESS; - int32_t w = decode->chunk.width; - int32_t h = decode->chunk.height; -- int32_t totsamp = 0; -+ uint64_t totsamp = 0; - int32_t* samptable = decode->sample_count_table; - size_t combSampSize = 0; - -@@ -351,38 +354,44 @@ unpack_sample_table ( - { - for (int32_t y = 0; y < h; ++y) - { -+ int32_t *cursampline = samptable + y * w; - int32_t prevsamp = 0; - for (int32_t x = 0; x < w; ++x) - { - int32_t nsamps = -- (int32_t) one_to_native32 ((uint32_t) samptable[y * w + x]); -- if (nsamps < 0) return EXR_ERR_INVALID_SAMPLE_DATA; -- samptable[y * w + x] = nsamps - prevsamp; -- prevsamp = nsamps; -+ (int32_t) one_to_native32 ((uint32_t) cursampline[x]); -+ if (nsamps < prevsamp) return EXR_ERR_INVALID_SAMPLE_DATA; -+ -+ cursampline[x] = nsamps - prevsamp; -+ prevsamp = nsamps; - } -- totsamp += prevsamp; -+ totsamp += (uint64_t)prevsamp; - } -- samptable[w * h] = totsamp; -+ if (totsamp >= (uint64_t)INT32_MAX) -+ return EXR_ERR_INVALID_SAMPLE_DATA; -+ samptable[w * h] = (int32_t)totsamp; - } - else - { - for (int32_t y = 0; y < h; ++y) - { -+ int32_t *cursampline = samptable + y * w; - int32_t prevsamp = 0; - for (int32_t x = 0; x < w; ++x) - { - int32_t nsamps = -- (int32_t) one_to_native32 ((uint32_t) samptable[y * w + x]); -- if (nsamps < 0) return EXR_ERR_INVALID_SAMPLE_DATA; -- samptable[y * w + x] = nsamps; -- prevsamp = nsamps; -+ (int32_t) one_to_native32 ((uint32_t) cursampline[x]); -+ if (nsamps < prevsamp) return EXR_ERR_INVALID_SAMPLE_DATA; -+ -+ cursampline[x] = nsamps; -+ prevsamp = nsamps; - } -- totsamp += prevsamp; -+ -+ totsamp += (uint64_t)prevsamp; - } - } - -- if (totsamp < 0 || -- (((uint64_t) totsamp) * combSampSize) > decode->chunk.unpacked_size) -+ if ((totsamp * combSampSize) > decode->chunk.unpacked_size) - { - rv = pctxt->report_error ( - pctxt, EXR_ERR_INVALID_SAMPLE_DATA, "Corrupt sample count table"); -diff --git a/src/lib/OpenEXRCore/unpack.c b/src/lib/OpenEXRCore/unpack.c -index b88c98974..1324508c5 100644 ---- a/src/lib/OpenEXRCore/unpack.c -+++ b/src/lib/OpenEXRCore/unpack.c -@@ -1196,9 +1196,10 @@ generic_unpack_deep_pointers (exr_decode_pipeline_t* decode) - if (outpix) - { - uint8_t* cdata = outpix; -+ - UNPACK_SAMPLES (samps) - } -- srcbuffer += bpc * samps; -+ srcbuffer += ((size_t) bpc) * ((size_t) samps); - } - } - sampbuffer += w; -@@ -1242,12 +1243,14 @@ generic_unpack_deep (exr_decode_pipeline_t* decode) - } - else - prevsamps = sampbuffer[w - 1]; -+ - srcbuffer += ((size_t) bpc) * ((size_t) prevsamps); - - if (incr_tot) totsamps += (size_t) prevsamps; - - continue; - } -+ - cdata += totsamps * ((size_t) ubpc); - - for (int x = 0; x < w; ++x) -@@ -1263,7 +1266,7 @@ generic_unpack_deep (exr_decode_pipeline_t* decode) - - UNPACK_SAMPLES (samps) - -- srcbuffer += bpc * samps; -+ srcbuffer += ((size_t) bpc) * ((size_t) samps); - if (incr_tot) totsamps += (size_t) samps; - } - } -@@ -1301,7 +1304,7 @@ internal_exr_match_decode ( - - if (isdeep) - { -- if ((decode->decode_flags & EXR_DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL)) -+ if ((decode->decode_flags & EXR_DECODE_NON_IMAGE_DATA_AS_POINTERS)) - return &generic_unpack_deep_pointers; - return &generic_unpack_deep; - } -diff --git a/src/lib/OpenEXRUtil/ImfCheckFile.cpp b/src/lib/OpenEXRUtil/ImfCheckFile.cpp -index 82f318a92..4d45dad69 100644 ---- a/src/lib/OpenEXRUtil/ImfCheckFile.cpp -+++ b/src/lib/OpenEXRUtil/ImfCheckFile.cpp -@@ -1200,13 +1200,88 @@ runChecks (T& source, bool reduceMemory, bool reduceTime) - return threw; - } - -+// This is not entirely needed in that the chunk info has the -+// total unpacked_size field which can be used for allocation -+// but this adds an additional point to use when debugging issues. -+static exr_result_t -+realloc_deepdata(exr_decode_pipeline_t* decode) -+{ -+ int32_t w = decode->chunk.width; -+ int32_t h = decode->chunk.height; -+ uint64_t totsamps = 0, bytes = 0; -+ const int32_t *sampbuffer = decode->sample_count_table; -+ std::vector* ud = static_cast*>( -+ decode->decoding_user_data); -+ -+ if ( ! ud ) -+ { -+ for (int c = 0; c < decode->channel_count; c++) -+ { -+ exr_coding_channel_info_t& outc = decode->channels[c]; -+ outc.decode_to_ptr = NULL; -+ outc.user_pixel_stride = outc.user_bytes_per_element; -+ outc.user_line_stride = 0; -+ } -+ return EXR_ERR_SUCCESS; -+ } -+ -+ if ((decode->decode_flags & -+ EXR_DECODE_SAMPLE_COUNTS_AS_INDIVIDUAL)) -+ { -+ for (int32_t y = 0; y < h; ++y) -+ { -+ for (int x = 0; x < w; ++x) -+ totsamps += sampbuffer[x]; -+ sampbuffer += w; -+ } -+ } -+ else -+ { -+ for (int32_t y = 0; y < h; ++y) -+ totsamps += sampbuffer[y*w + w - 1]; -+ } -+ -+ for (int c = 0; c < decode->channel_count; c++) -+ { -+ exr_coding_channel_info_t& outc = decode->channels[c]; -+ bytes += totsamps * outc.user_bytes_per_element; -+ } -+ -+ if (bytes >= gMaxBytesPerDeepScanline * h) -+ { -+ for (int c = 0; c < decode->channel_count; c++) -+ { -+ exr_coding_channel_info_t& outc = decode->channels[c]; -+ outc.decode_to_ptr = NULL; -+ outc.user_pixel_stride = outc.user_bytes_per_element; -+ outc.user_line_stride = 0; -+ } -+ return EXR_ERR_SUCCESS; -+ } -+ -+ if (ud->size () < bytes) -+ ud->resize (bytes); -+ -+ uint8_t* dptr = &((*ud)[0]); -+ for (int c = 0; c < decode->channel_count; c++) -+ { -+ exr_coding_channel_info_t& outc = decode->channels[c]; -+ outc.decode_to_ptr = dptr; -+ outc.user_pixel_stride = outc.user_bytes_per_element; -+ outc.user_line_stride = 0; -+ -+ dptr += totsamps * (uint64_t) outc.user_bytes_per_element; -+ } -+ return EXR_ERR_SUCCESS; -+} -+ - //////////////////////////////////////// - - bool - readCoreScanlinePart ( - exr_context_t f, int part, bool reduceMemory, bool reduceTime) - { -- exr_result_t rv; -+ exr_result_t rv, frv; - exr_attr_box2i_t datawin; - rv = exr_get_data_window (f, part, &datawin); - if (rv != EXR_ERR_SUCCESS) return true; -@@ -1224,6 +1299,8 @@ readCoreScanlinePart ( - rv = exr_get_scanlines_per_chunk (f, part, &lines_per_chunk); - if (rv != EXR_ERR_SUCCESS) return true; - -+ frv = rv; -+ - for (uint64_t chunk = 0; chunk < height; chunk += lines_per_chunk) - { - exr_chunk_info_t cinfo = {0}; -@@ -1232,6 +1309,7 @@ readCoreScanlinePart ( - rv = exr_read_scanline_chunk_info (f, part, y, &cinfo); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) break; - continue; - } -@@ -1253,19 +1331,32 @@ readCoreScanlinePart ( - (uint64_t) lines_per_chunk; - } - -- // TODO: check we are supposed to multiple by lines per chunk above - doread = true; -- if (reduceMemory && bytes >= gMaxBytesPerScanline) doread = false; - -- if (doread) imgdata.resize (bytes); -+ if (cinfo.type == EXR_STORAGE_DEEP_SCANLINE) -+ { -+ decoder.decoding_user_data = &imgdata; -+ decoder.realloc_nonimage_data_fn = &realloc_deepdata; -+ } -+ else -+ { -+ if (reduceMemory && bytes >= gMaxBytesPerScanline) doread = false; -+ -+ if (doread) imgdata.resize (bytes); -+ } - rv = exr_decoding_choose_default_routines (f, part, &decoder); -- if (rv != EXR_ERR_SUCCESS) break; -+ if (rv != EXR_ERR_SUCCESS) -+ { -+ frv = rv; -+ break; -+ } - } - else - { - rv = exr_decoding_update (f, part, &cinfo, &decoder); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) break; - continue; - } -@@ -1273,20 +1364,25 @@ readCoreScanlinePart ( - - if (doread) - { -- uint8_t* dptr = &(imgdata[0]); -- for (int c = 0; c < decoder.channel_count; c++) -+ if (cinfo.type != EXR_STORAGE_DEEP_SCANLINE) - { -- exr_coding_channel_info_t& outc = decoder.channels[c]; -- outc.decode_to_ptr = dptr; -- outc.user_pixel_stride = outc.user_bytes_per_element; -- outc.user_line_stride = outc.user_pixel_stride * width; -- dptr += width * (uint64_t) outc.user_bytes_per_element * -+ uint8_t* dptr = &(imgdata[0]); -+ for (int c = 0; c < decoder.channel_count; c++) -+ { -+ exr_coding_channel_info_t& outc = decoder.channels[c]; -+ outc.decode_to_ptr = dptr; -+ outc.user_pixel_stride = outc.user_bytes_per_element; -+ outc.user_line_stride = outc.user_pixel_stride * width; -+ -+ dptr += width * (uint64_t) outc.user_bytes_per_element * - (uint64_t) lines_per_chunk; -+ } - } - - rv = exr_decoding_run (f, part, &decoder); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) break; - } - } -@@ -1294,7 +1390,7 @@ readCoreScanlinePart ( - - exr_decoding_destroy (f, &decoder); - -- return (rv != EXR_ERR_SUCCESS); -+ return (frv != EXR_ERR_SUCCESS); - } - - //////////////////////////////////////// -@@ -1303,7 +1399,7 @@ bool - readCoreTiledPart ( - exr_context_t f, int part, bool reduceMemory, bool reduceTime) - { -- exr_result_t rv; -+ exr_result_t rv, frv; - - exr_attr_box2i_t datawin; - rv = exr_get_data_window (f, part, &datawin); -@@ -1321,6 +1417,7 @@ readCoreTiledPart ( - rv = exr_get_tile_levels (f, part, &levelsx, &levelsy); - if (rv != EXR_ERR_SUCCESS) return true; - -+ frv = rv; - bool keepgoing = true; - for (int32_t ylevel = 0; keepgoing && ylevel < levelsy; ++ylevel) - { -@@ -1330,6 +1427,7 @@ readCoreTiledPart ( - rv = exr_get_level_sizes (f, part, xlevel, ylevel, &levw, &levh); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) - { - keepgoing = false; -@@ -1342,6 +1440,7 @@ readCoreTiledPart ( - rv = exr_get_tile_sizes (f, part, xlevel, ylevel, &curtw, &curth); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) - { - keepgoing = false; -@@ -1371,6 +1470,7 @@ readCoreTiledPart ( - f, part, tx, ty, xlevel, ylevel, &cinfo); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) - { - keepgoing = false; -@@ -1385,6 +1485,7 @@ readCoreTiledPart ( - exr_decoding_initialize (f, part, &cinfo, &decoder); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - keepgoing = false; - break; - } -@@ -1406,14 +1507,23 @@ readCoreTiledPart ( - } - - doread = true; -- if (reduceMemory && bytes >= gMaxTileBytes) -- doread = false; -+ if (cinfo.type == EXR_STORAGE_DEEP_TILED) -+ { -+ decoder.decoding_user_data = &tiledata; -+ decoder.realloc_nonimage_data_fn = &realloc_deepdata; -+ } -+ else -+ { -+ if (reduceMemory && bytes >= gMaxTileBytes) -+ doread = false; - -- if (doread) tiledata.resize (bytes); -+ if (doread) tiledata.resize (bytes); -+ } - rv = exr_decoding_choose_default_routines ( - f, part, &decoder); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - keepgoing = false; - break; - } -@@ -1423,6 +1533,7 @@ readCoreTiledPart ( - rv = exr_decoding_update (f, part, &cinfo, &decoder); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) - { - keepgoing = false; -@@ -1434,24 +1545,28 @@ readCoreTiledPart ( - - if (doread) - { -- uint8_t* dptr = &(tiledata[0]); -- for (int c = 0; c < decoder.channel_count; c++) -+ if (cinfo.type != EXR_STORAGE_DEEP_TILED) - { -- exr_coding_channel_info_t& outc = -- decoder.channels[c]; -- outc.decode_to_ptr = dptr; -- outc.user_pixel_stride = -- outc.user_bytes_per_element; -- outc.user_line_stride = -- outc.user_pixel_stride * curtw; -- dptr += (uint64_t) curtw * -+ uint8_t* dptr = &(tiledata[0]); -+ for (int c = 0; c < decoder.channel_count; c++) -+ { -+ exr_coding_channel_info_t& outc = -+ decoder.channels[c]; -+ outc.decode_to_ptr = dptr; -+ outc.user_pixel_stride = -+ outc.user_bytes_per_element; -+ outc.user_line_stride = -+ outc.user_pixel_stride * curtw; -+ dptr += (uint64_t) curtw * - (uint64_t) outc.user_bytes_per_element * - (uint64_t) curth; -+ } - } - - rv = exr_decoding_run (f, part, &decoder); - if (rv != EXR_ERR_SUCCESS) - { -+ frv = rv; - if (reduceTime) - { - keepgoing = false; -@@ -1486,17 +1601,14 @@ checkCoreFile (exr_context_t f, bool reduceMemory, bool reduceTime) - rv = exr_get_storage (f, p, &store); - if (rv != EXR_ERR_SUCCESS) return true; - -- // TODO: Need to fill this in -- if (store == EXR_STORAGE_DEEP_SCANLINE || -- store == EXR_STORAGE_DEEP_TILED) -- continue; -- -- if (store == EXR_STORAGE_SCANLINE) -+ if (store == EXR_STORAGE_SCANLINE || -+ store == EXR_STORAGE_DEEP_SCANLINE) - { - if (readCoreScanlinePart (f, p, reduceMemory, reduceTime)) - return true; - } -- else if (store == EXR_STORAGE_TILED) -+ else if (store == EXR_STORAGE_TILED || -+ store == EXR_STORAGE_DEEP_TILED) - { - if (readCoreTiledPart (f, p, reduceMemory, reduceTime)) return true; - } - diff --git a/openexr.changes b/openexr.changes index 3e50cd3..36899dd 100644 --- a/openexr.changes +++ b/openexr.changes @@ -1,3 +1,18 @@ +------------------------------------------------------------------- +Wed Feb 14 14:32:50 UTC 2024 - pgajdos@suse.com + +- version update to 3.2.2 [bsc#1219498] + * [CVE-2023-5841](https://takeonme.org/cves/CVE-2023-5841.html). + Note that this bug is present in the C++ API (since v3.1.0), although + it is in a routine that is predominantly used for development and + testing. It is not likely to appear in production code. + * OSS-fuzz [66491](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66491) + Out-of-memory in openexr_exrcorecheck_fuzzer + * OSS-fuzz [66489](https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66489) + Null-dereference in `Imf_3_3::realloc_deepdata` +- deleted patches + - openexr-CVE-2023-5841.patch (upstreamed) + ------------------------------------------------------------------- Wed Feb 7 10:31:23 UTC 2024 - pgajdos@suse.com diff --git a/openexr.spec b/openexr.spec index 195608a..409b934 100644 --- a/openexr.spec +++ b/openexr.spec @@ -22,7 +22,7 @@ %define sonum 31 %global so_suffix -3_2 Name: openexr -Version: 3.2.1 +Version: 3.2.2 Release: 0 Summary: Utilities for working with HDR images in OpenEXR format License: BSD-3-Clause @@ -30,8 +30,6 @@ Group: Development/Libraries/C and C++ URL: https://www.openexr.com/ Source0: https://github.com/openexr/openexr/archive/v%{version}.tar.gz Source2: baselibs.conf -# CVE-2023-5841 [bsc#1219498], heap-based buffer overflow in generic_unpack_deep() -Patch0: openexr-CVE-2023-5841.patch BuildRequires: cmake >= 3.12 BuildRequires: freeglut-devel BuildRequires: gcc-c++ diff --git a/v3.2.1.tar.gz b/v3.2.1.tar.gz deleted file mode 100644 index 93d2ca6..0000000 --- a/v3.2.1.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:61e175aa2203399fb3c8c2288752fbea3c2637680d50b6e306ea5f8ffdd46a9b -size 18824332 diff --git a/v3.2.2.tar.gz b/v3.2.2.tar.gz new file mode 100644 index 0000000..cf0e9ca --- /dev/null +++ b/v3.2.2.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65de6459c245a4977ce4d7777e70b30d7ef48ec38e0cfb10205706ca50a8bf2e +size 18825996