From 644f18a6dc1c4e331eb86df12bbdc1be0a735882 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Mon, 4 May 2026 18:28:53 -0400 Subject: [PATCH] import CS git LibRaw-0.19.5-6.el8_10 --- .LibRaw.metadata | 1 + ...ibRaw-CVE-2026-20889-TALOS-2026-2358.patch | 92 +++++ ...ibRaw-CVE-2026-21413-TALOS-2026-2331.patch | 24 ++ ...ibRaw-CVE-2026-24660-TALOS-2026-2359.patch | 334 ++++++++++++++++++ SPECS/LibRaw.spec | 20 +- 5 files changed, 469 insertions(+), 2 deletions(-) create mode 100644 .LibRaw.metadata create mode 100644 SOURCES/LibRaw-CVE-2026-20889-TALOS-2026-2358.patch create mode 100644 SOURCES/LibRaw-CVE-2026-21413-TALOS-2026-2331.patch create mode 100644 SOURCES/LibRaw-CVE-2026-24660-TALOS-2026-2359.patch diff --git a/.LibRaw.metadata b/.LibRaw.metadata new file mode 100644 index 0000000..5557586 --- /dev/null +++ b/.LibRaw.metadata @@ -0,0 +1 @@ +c151995b6f17a0ccef7fbc1dcb982f0ccb04d934 SOURCES/LibRaw-0.19.5.tar.gz diff --git a/SOURCES/LibRaw-CVE-2026-20889-TALOS-2026-2358.patch b/SOURCES/LibRaw-CVE-2026-20889-TALOS-2026-2358.patch new file mode 100644 index 0000000..adf8b7b --- /dev/null +++ b/SOURCES/LibRaw-CVE-2026-20889-TALOS-2026-2358.patch @@ -0,0 +1,92 @@ +From 7e315d12429c91aa7d7e6402db00ac0cdd173ad5 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 29 Apr 2026 23:42:31 +0200 +Subject: [PATCH] Fix for TALOS-2026-2358 + +(backported from commit b9809e410d07ca7bf408e6d036615fb34f8c47cc) +--- + internal/libraw_x3f.cpp | 7 +++++++ + src/libraw_cxx.cpp | 20 +++++++++++++++++++- + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/internal/libraw_x3f.cpp b/internal/libraw_x3f.cpp +index 49918e99d2ce..2976eaf70929 100644 +--- a/internal/libraw_x3f.cpp ++++ b/internal/libraw_x3f.cpp +@@ -1579,7 +1579,14 @@ static uint32_t read_data_block(void **data, + if (fpos + size > I->input.file->size()) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + ++ // All known files from real cameras are many times smaller than 1 GB, so the hard limit is OK here. ++ ++ if(size > 1024*1024*1024) ++ throw LIBRAW_EXCEPTION_ALLOC; ++ + *data = (void *)malloc(size); ++ if (!*data) ++ throw LIBRAW_EXCEPTION_ALLOC; + + GETN(*data, size); + +diff --git a/src/libraw_cxx.cpp b/src/libraw_cxx.cpp +index 51d0ebbc9fc8..a5cdf8ae6b01 100644 +--- a/src/libraw_cxx.cpp ++++ b/src/libraw_cxx.cpp +@@ -4432,6 +4432,8 @@ int LibRaw::unpack_thumb(void) + { + x3f_thumb_loader(); + SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD); ++ if (!T.twidth && !T.theight) ++ return LIBRAW_NO_THUMBNAIL; + return 0; + } + else +@@ -6380,6 +6382,7 @@ void LibRaw::x3f_thumb_loader() + { + try + { ++ INT64 checked_size = x3f_thumb_size(); // This value was checked at upper level? + x3f_t *x3f = (x3f_t *)_x3f_data; + if (!x3f) + return; // No data pointer set +@@ -6397,6 +6400,12 @@ void LibRaw::x3f_thumb_loader() + imgdata.thumbnail.tcolors = 3; + if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_JPEG) + { ++ INT64 alloc_size = ID->data_size; ++ if ((alloc_size > 2 * checked_size) || (alloc_size > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB)) ++ throw LIBRAW_EXCEPTION_TOOBIG; ++ if(alloc_size < 64LL) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++ + imgdata.thumbnail.thumb = (char *)malloc(ID->data_size); + merror(imgdata.thumbnail.thumb, "LibRaw::x3f_thumb_loader()"); + memmove(imgdata.thumbnail.thumb, ID->data, ID->data_size); +@@ -6404,6 +6413,12 @@ void LibRaw::x3f_thumb_loader() + } + else if (imgdata.thumbnail.tformat == LIBRAW_THUMBNAIL_BITMAP) + { ++ INT64 alloc_size = INT64(ID->columns) * INT64(ID->rows) * 3LL; ++ if ((alloc_size > 2 * checked_size) || ++ (alloc_size > 1024LL * 1024LL * LIBRAW_MAX_THUMBNAIL_MB)) throw LIBRAW_EXCEPTION_TOOBIG; ++ if (alloc_size < 64LL) ++ throw LIBRAW_EXCEPTION_IO_CORRUPT; ++ + imgdata.thumbnail.tlength = ID->columns * ID->rows * 3; + imgdata.thumbnail.thumb = (char *)malloc(ID->columns * ID->rows * 3); + merror(imgdata.thumbnail.thumb, "LibRaw::x3f_thumb_loader()"); +@@ -6421,7 +6436,10 @@ void LibRaw::x3f_thumb_loader() + } + catch (...) + { +- // do nothing ++ // no rethrow: handled at upper level ++ imgdata.thumbnail.twidth = 0; ++ imgdata.thumbnail.theight = 0; ++ imgdata.thumbnail.tcolors = 0; + } + } + +-- +2.53.0 + diff --git a/SOURCES/LibRaw-CVE-2026-21413-TALOS-2026-2331.patch b/SOURCES/LibRaw-CVE-2026-21413-TALOS-2026-2331.patch new file mode 100644 index 0000000..5711815 --- /dev/null +++ b/SOURCES/LibRaw-CVE-2026-21413-TALOS-2026-2331.patch @@ -0,0 +1,24 @@ +diff -urNp LibRaw-0.19.5.orig/dcraw/dcraw.c LibRaw-0.19.5/dcraw/dcraw.c +--- LibRaw-0.19.5.orig/dcraw/dcraw.c 2026-04-28 23:52:51.314912726 +0200 ++++ LibRaw-0.19.5/dcraw/dcraw.c 2026-04-29 00:05:10.714922134 +0200 +@@ -953,7 +953,7 @@ void CLASS lossless_jpeg_load_raw() + } + if (raw_width == 3984 && (col -= 2) < 0) + col += (row--,raw_width); +- if ((unsigned) row < raw_height) RAW(row,col) = val; ++ if (((unsigned) row < raw_height) && ((unsigned) col < raw_width)) RAW(row,col) = val; + if (++col >= raw_width) + col = (row++,0); + } +diff -urNp LibRaw-0.19.5.orig/internal/dcraw_common.cpp LibRaw-0.19.5/internal/dcraw_common.cpp +--- LibRaw-0.19.5.orig/internal/dcraw_common.cpp 2026-04-28 23:52:51.315669819 +0200 ++++ LibRaw-0.19.5/internal/dcraw_common.cpp 2026-04-29 00:03:21.023739250 +0200 +@@ -1067,7 +1067,7 @@ void CLASS lossless_jpeg_load_raw() + #else + longjmp(failure, 3); + #endif +- if ((unsigned)row < raw_height) ++ if (((unsigned)row < raw_height) && ((unsigned)col < raw_width)) + RAW(row, col) = val; + if (++col >= raw_width) + col = (row++, 0); diff --git a/SOURCES/LibRaw-CVE-2026-24660-TALOS-2026-2359.patch b/SOURCES/LibRaw-CVE-2026-24660-TALOS-2026-2359.patch new file mode 100644 index 0000000..e0eb689 --- /dev/null +++ b/SOURCES/LibRaw-CVE-2026-24660-TALOS-2026-2359.patch @@ -0,0 +1,334 @@ +From 92492c81b2fd2b600f357b32a1e03bff85db65b9 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 30 Apr 2026 14:27:27 +0200 +Subject: [PATCH] X3F decoder: implemented hard single allocation limit + +... via LIBRAW_X3F_ALLOC_LIMIT_MB define; allocation size calculation +converted to 64 bit arithm; fix for TALOS-2026-2359. + +(backported from commit ac151a829b8d3e4c74fa3aefa8a029c3cc3f857f) +--- + internal/libraw_x3f.cpp | 101 ++++++++++++++++++++++++---------------- + libraw/libraw_const.h | 6 +++ + 2 files changed, 67 insertions(+), 40 deletions(-) + +diff --git a/internal/libraw_x3f.cpp b/internal/libraw_x3f.cpp +index 2976eaf70929..8b159dda18c9 100644 +--- a/internal/libraw_x3f.cpp ++++ b/internal/libraw_x3f.cpp +@@ -474,6 +474,36 @@ x3f_return_t x3f_delete(x3f_t *x3f); + /* Reading and writing - assuming little endian in the file */ + /* --------------------------------------------------------------------- */ + ++static void *x3f_limited_malloc(UINT64 sz) ++{ ++ if (sz > LIBRAW_X3F_ALLOC_LIMIT_MB * 1024ULL * 1024ULL) ++ throw LIBRAW_EXCEPTION_TOOBIG; ++ void *ret = malloc(sz); ++ if (!ret) ++ throw LIBRAW_EXCEPTION_ALLOC; ++ return ret; ++} ++ ++static void *x3f_limited_calloc(UINT64 n, UINT64 sz) ++{ ++ if (sz * n > LIBRAW_X3F_ALLOC_LIMIT_MB * 1024ULL * 1024ULL) ++ throw LIBRAW_EXCEPTION_TOOBIG; ++ void *ret = calloc(n, sz); ++ if (!ret) ++ throw LIBRAW_EXCEPTION_ALLOC; ++ return ret; ++} ++ ++static void *x3f_limited_realloc(void *ptr, UINT64 sz) ++{ ++ if (sz > LIBRAW_X3F_ALLOC_LIMIT_MB * 1024ULL * 1024ULL) ++ throw LIBRAW_EXCEPTION_TOOBIG; ++ void *ret = realloc(ptr, sz); ++ if (!ret) ++ throw LIBRAW_EXCEPTION_ALLOC; ++ return ret; ++} ++ + static int x3f_get1(LibRaw_abstract_datastream *f) + { + /* Little endian file */ +@@ -536,7 +566,7 @@ union {int32_t i; float f;} _tmp; \ + do { \ + int _i; \ + (_T).size = (_NUM); \ +- (_T).element = (_TYPE *)realloc((_T).element, \ ++ (_T).element = (_TYPE *)x3f_limited_realloc((_T).element, \ + (_NUM)*sizeof((_T).element[0])); \ + for (_i = 0; _i < (_T).size; _i++) \ + _GETX((_T).element[_i]); \ +@@ -546,7 +576,7 @@ union {int32_t i; float f;} _tmp; \ + do { \ + int _i; \ + (_T).size = (_NUM); \ +- (_T).element = (x3f_property_t *)realloc((_T).element, \ ++ (_T).element = (x3f_property_t *)x3f_limited_realloc((_T).element, \ + (_NUM)*sizeof((_T).element[0])); \ + for (_i = 0; _i < (_T).size; _i++) { \ + GET4((_T).element[_i].name_offset); \ +@@ -560,7 +590,7 @@ union {int32_t i; float f;} _tmp; \ + (_T).element = NULL; \ + for (_i = 0; ; _i++) { \ + (_T).size = _i + 1; \ +- (_T).element = (x3f_true_huffman_element_t *)realloc((_T).element, \ ++ (_T).element = (x3f_true_huffman_element_t *)x3f_limited_realloc((_T).element, \ + (_i + 1)*sizeof((_T).element[0])); \ + GET1((_T).element[_i].code_size); \ + GET1((_T).element[_i].code); \ +@@ -583,7 +613,7 @@ static void new_huffman_tree(x3f_hufftree_t *HTP, int bits) + + HTP->free_node_index = 0; + HTP->nodes = (x3f_huffnode_t *) +- calloc(1, HUF_TREE_MAX_NODES(leaves)*sizeof(x3f_huffnode_t)); ++ x3f_limited_calloc(1, HUF_TREE_MAX_NODES(leaves)*sizeof(x3f_huffnode_t)); + } + + /* --------------------------------------------------------------------- */ +@@ -608,7 +638,7 @@ static void cleanup_true(x3f_true_t **TRUP) + + static x3f_true_t *new_true(x3f_true_t **TRUP) + { +- x3f_true_t *TRU = (x3f_true_t *)calloc(1, sizeof(x3f_true_t)); ++ x3f_true_t *TRU = (x3f_true_t *)x3f_limited_calloc(1, sizeof(x3f_true_t)); + + cleanup_true(TRUP); + +@@ -639,7 +669,7 @@ static void cleanup_quattro(x3f_quattro_t **QP) + + static x3f_quattro_t *new_quattro(x3f_quattro_t **QP) + { +- x3f_quattro_t *Q = (x3f_quattro_t *)calloc(1, sizeof(x3f_quattro_t)); ++ x3f_quattro_t *Q = (x3f_quattro_t *)x3f_limited_calloc(1, sizeof(x3f_quattro_t)); + int i; + + cleanup_quattro(QP); +@@ -682,7 +712,7 @@ static void cleanup_huffman(x3f_huffman_t **HUFP) + + static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP) + { +- x3f_huffman_t *HUF = (x3f_huffman_t *)calloc(1, sizeof(x3f_huffman_t)); ++ x3f_huffman_t *HUF = (x3f_huffman_t *)x3f_limited_calloc(1, sizeof(x3f_huffman_t)); + + cleanup_huffman(HUFP); + +@@ -712,9 +742,7 @@ static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP) + { + if (!infile) return NULL; + INT64 fsize = infile->size(); +- x3f_t *x3f = (x3f_t *)calloc(1, sizeof(x3f_t)); +- if(!x3f) +- throw LIBRAW_EXCEPTION_ALLOC; ++ x3f_t *x3f = (x3f_t *)x3f_limited_calloc(1, sizeof(x3f_t)); + try { + x3f_info_t *I = NULL; + x3f_header_t *H = NULL; +@@ -773,7 +801,7 @@ static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP) + + if (DS->num_directory_entries > 0) { + size_t size = DS->num_directory_entries * sizeof(x3f_directory_entry_t); +- DS->directory_entry = (x3f_directory_entry_t *)calloc(1, size); ++ DS->directory_entry = (x3f_directory_entry_t *)x3f_limited_calloc(1, size); + } + + /* Traverse the directory */ +@@ -1579,14 +1607,7 @@ static uint32_t read_data_block(void **data, + if (fpos + size > I->input.file->size()) + throw LIBRAW_EXCEPTION_IO_CORRUPT; + +- // All known files from real cameras are many times smaller than 1 GB, so the hard limit is OK here. +- +- if(size > 1024*1024*1024) +- throw LIBRAW_EXCEPTION_ALLOC; +- +- *data = (void *)malloc(size); +- if (!*data) +- throw LIBRAW_EXCEPTION_ALLOC; ++ *data = (void *)x3f_limited_malloc(size); + + GETN(*data, size); + +@@ -1719,35 +1740,35 @@ static void x3f_load_true(x3f_info_t *I, + uint32_t columns = Q->plane[0].columns; + uint32_t rows = Q->plane[0].rows; + uint32_t channels = 3; +- uint32_t size = columns * rows * channels; ++ UINT64 size = UINT64(columns) * UINT64(rows) * UINT64(channels); + + TRU->x3rgb16.columns = columns; + TRU->x3rgb16.rows = rows; + TRU->x3rgb16.channels = channels; + TRU->x3rgb16.row_stride = columns * channels; +- TRU->x3rgb16.buf = malloc(sizeof(uint16_t)*size); ++ TRU->x3rgb16.buf = x3f_limited_malloc(sizeof(uint16_t)*size); + TRU->x3rgb16.data = (uint16_t *) TRU->x3rgb16.buf; + + columns = Q->plane[2].columns; + rows = Q->plane[2].rows; + channels = 1; +- size = columns * rows * channels; ++ size = UINT64(columns) * UINT64(rows) * UINT64(channels); + + Q->top16.columns = columns; + Q->top16.rows = rows; + Q->top16.channels = channels; + Q->top16.row_stride = columns * channels; +- Q->top16.buf = malloc(sizeof(uint16_t)*size); ++ Q->top16.buf = x3f_limited_malloc(sizeof(uint16_t)*size); + Q->top16.data = (uint16_t *)Q->top16.buf; + + } else { +- uint32_t size = ID->columns * ID->rows * 3; ++ UINT64 size = UINT64(ID->columns) * UINT64(ID->rows) * 3ULL; + + TRU->x3rgb16.columns = ID->columns; + TRU->x3rgb16.rows = ID->rows; + TRU->x3rgb16.channels = 3; + TRU->x3rgb16.row_stride = ID->columns * 3; +- TRU->x3rgb16.buf =malloc(sizeof(uint16_t)*size); ++ TRU->x3rgb16.buf = x3f_limited_malloc(sizeof(uint16_t)*size); + TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf; + } + +@@ -1802,7 +1823,7 @@ static void x3f_load_huffman(x3f_info_t *I, + x3f_directory_entry_header_t *DEH = &DE->header; + x3f_image_data_t *ID = &DEH->data_subsection.image_data; + x3f_huffman_t *HUF = new_huffman(&ID->huffman); +- uint32_t size; ++ UINT64 size; + + if (use_map_table) { + int table_size = 1<type_format) { + case X3F_IMAGE_RAW_HUFFMAN_X530: + case X3F_IMAGE_RAW_HUFFMAN_10BIT: +- size = ID->columns * ID->rows * 3; ++ size = UINT64(ID->columns) * UINT64(ID->rows) * 3ULL; + HUF->x3rgb16.columns = ID->columns; + HUF->x3rgb16.rows = ID->rows; + HUF->x3rgb16.channels = 3; + HUF->x3rgb16.row_stride = ID->columns * 3; +- HUF->x3rgb16.buf = malloc(sizeof(uint16_t)*size); ++ HUF->x3rgb16.buf = x3f_limited_malloc(sizeof(uint16_t)*size); + HUF->x3rgb16.data = (uint16_t *)HUF->x3rgb16.buf; + break; + case X3F_IMAGE_THUMB_HUFFMAN: +- size = ID->columns * ID->rows * 3; ++ size = UINT64(ID->columns) * UINT64(ID->rows) * 3ULL; + HUF->rgb8.columns = ID->columns; + HUF->rgb8.rows = ID->rows; + HUF->rgb8.channels = 3; + HUF->rgb8.row_stride = ID->columns * 3; +- HUF->rgb8.buf = malloc(sizeof(uint8_t)*size); ++ HUF->rgb8.buf = x3f_limited_malloc(sizeof(uint8_t)*size); + HUF->rgb8.data = (uint8_t *)HUF->rgb8.buf; + break; + default: +@@ -1923,7 +1944,7 @@ static void x3f_load_camf_decode_type2(x3f_camf_t *CAMF) + int i; + + CAMF->decoded_data_size = CAMF->data_size; +- CAMF->decoded_data = malloc(CAMF->decoded_data_size); ++ CAMF->decoded_data = x3f_limited_malloc(CAMF->decoded_data_size); + + for (i=0; idata_size; i++) { + uint8_t old, _new; +@@ -1963,7 +1984,7 @@ static void camf_decode_type4(x3f_camf_t *CAMF) + + CAMF->decoded_data_size = dst_size; + +- CAMF->decoded_data = malloc(CAMF->decoded_data_size); ++ CAMF->decoded_data = x3f_limited_malloc(CAMF->decoded_data_size); + memset(CAMF->decoded_data, 0, CAMF->decoded_data_size); + + dst = (uint8_t *)CAMF->decoded_data; +@@ -2038,7 +2059,7 @@ static void x3f_load_camf_decode_type4(x3f_camf_t *CAMF) + for (i=0, p = (uint8_t*)CAMF->data; *p != 0; i++) { + /* TODO: Is this too expensive ??*/ + element = +- (x3f_true_huffman_element_t *)realloc(element, (i+1)*sizeof(*element)); ++ (x3f_true_huffman_element_t *)x3f_limited_realloc(element, (i+1)*sizeof(*element)); + + element[i].code_size = *p++; + element[i].code = *p++; +@@ -2077,7 +2098,7 @@ static void camf_decode_type5(x3f_camf_t *CAMF) + int32_t i; + + CAMF->decoded_data_size = CAMF->t5.decoded_data_size; +- CAMF->decoded_data = malloc(CAMF->decoded_data_size); ++ CAMF->decoded_data = x3f_limited_malloc(CAMF->decoded_data_size); + + dst = (uint8_t *)CAMF->decoded_data; + +@@ -2100,7 +2121,7 @@ static void x3f_load_camf_decode_type5(x3f_camf_t *CAMF) + for (i=0, p = (uint8_t*)CAMF->data; *p != 0; i++) { + /* TODO: Is this too expensive ??*/ + element = +- (x3f_true_huffman_element_t *)realloc(element, (i+1)*sizeof(*element)); ++ (x3f_true_huffman_element_t *)x3f_limited_realloc(element, (i+1)*sizeof(*element)); + + element[i].code_size = *p++; + element[i].code = *p++; +@@ -2144,8 +2165,8 @@ static void x3f_setup_camf_property_entry(camf_entry_t *entry) + entry->property_num = *(uint32_t *)v; + uint32_t off = *(uint32_t *)(v + 4); + +- entry->property_name = (char **)malloc(num*sizeof(uint8_t*)); +- entry->property_value = (uint8_t **)malloc(num*sizeof(uint8_t*)); ++ entry->property_name = (char **)x3f_limited_malloc(num*sizeof(uint8_t*)); ++ entry->property_value = (uint8_t **)x3f_limited_malloc(num*sizeof(uint8_t*)); + + for (i=0; imatrix_decoded = malloc(size); ++ entry->matrix_decoded = x3f_limited_malloc(size); + + switch (element_size) { + case 4: +@@ -2271,7 +2292,7 @@ static void x3f_setup_camf_matrix_entry(camf_entry_t *entry) + entry->matrix_data_off = *(uint32_t *)(v + 8); + camf_dim_entry_t *dentry = + entry->matrix_dim_entry = +- (camf_dim_entry_t*)malloc(dim*sizeof(camf_dim_entry_t)); ++ (camf_dim_entry_t*)x3f_limited_malloc(dim*sizeof(camf_dim_entry_t)); + + for (i=0; i - 0.19.5-6 +- Backport fix for CVE-2026-24660 from upstream +Resolves: RHEL-165412 + +* Tue Apr 28 2026 Debarshi Ray - 0.19.5-5 +- Backport fixes for CVE-2026-20889 and CVE-2026-21413 from upstream +- Migrate to SPDX license +Resolves: RHEL-165404, RHEL-165408 + * Mon Oct 23 2023 Debarshi Ray - 0.19.5-4 - Backport fix for CVE-2021-32142 from upstream Resolves: RHEL-9523