public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Elliott Sales de Andrade <quantum.analyst@gmail.com>
To: git-commits@fedoraproject.org
Subject: [rpms/libxls] f44: Backport CVE patches
Date: Sat, 15 Aug 2026 20:12:44 GMT [thread overview]
Message-ID: <178682476487.1.446825865215713500.rpms-libxls-fa47cdfd7ff8@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/libxls
Branch : f44
Commit : fa47cdfd7ff8ead69de376d8b91fdf7c093ca6bc
Author : Elliott Sales de Andrade <quantum.analyst@gmail.com>
Date : 2026-08-15T15:29:53-04:00
Stats : +234/-1 in 4 file(s)
URL : https://src.fedoraproject.org/rpms/libxls/c/fa47cdfd7ff8ead69de376d8b91fdf7c093ca6bc?branch=f44
Log:
Backport CVE patches
- fixes CVE-2026-26824 (rhbz#2484566)
- fixes CVE-2026-26825 (rhbz#2484567)
---
diff --git a/157.patch b/157.patch
new file mode 100644
index 0000000..07959d7
--- /dev/null
+++ b/157.patch
@@ -0,0 +1,60 @@
+From a96c405e90a1a5dfebfe833032d8532b5499d080 Mon Sep 17 00:00:00 2001
+From: chenchongyf1 <ubuntu@PC2-HZ20017272.hikvision.com>
+Date: Tue, 4 Aug 2026 20:41:03 +0800
+Subject: [PATCH] Fix use of uninitialized memory in OLE parsing (Fixes #156,
+ CVE-2026-26825)
+
+- Zero-initialize OLE stream allocations in ole_malloc using calloc.
+- Initialize OLE2Header and PSS structs with calloc.
+- Explicitly set SecID and SSecID FAT arrays to FREESECT (0xFF) upon allocation to prevent reading uninitialized heap memory during sector validation.
+---
+ src/ole.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/src/ole.c b/src/ole.c
+index 4a75be4..0442f97 100644
+--- a/src/ole.c
++++ b/src/ole.c
+@@ -63,7 +63,7 @@ static void *ole_malloc(size_t len) {
+ if (len > (1<<24) || len == 0) {
+ return NULL;
+ }
+- return malloc(len);
++ return calloc(1, len);
+ }
+
+ static void *ole_realloc(void *ptr, size_t len) {
+@@ -402,7 +402,7 @@ static size_t ole2_fread(OLE2 *ole2, void *buffer, size_t buffer_len, size_t siz
+ // read header and check magic numbers
+ static ssize_t ole2_read_header(OLE2 *ole) {
+ ssize_t bytes_read = 0, total_bytes_read = 0;
+- OLE2Header *oleh = malloc(sizeof(OLE2Header));
++ OLE2Header *oleh = calloc(1, sizeof(OLE2Header));
+ if (ole2_fread(ole, oleh, sizeof(OLE2Header), sizeof(OLE2Header)) != 1) {
+ total_bytes_read = -1;
+ goto cleanup;
+@@ -480,7 +480,7 @@ static ssize_t ole2_read_body(OLE2 *ole) {
+ total_bytes_read = -1;
+ goto cleanup;
+ }
+- pss = malloc(sizeof(PSS));
++ pss = calloc(1, sizeof(PSS));
+ do {
+ if ((bytes_read = ole2_read(pss,1,sizeof(PSS),olest)) == -1) {
+ total_bytes_read = -1;
+@@ -779,6 +779,7 @@ static ssize_t read_MSAT_trailer(OLE2 *ole2) {
+ return -1;
+ }
+ ole2->SSecIDCount = ole2->csfat*(size_t)ole2->lsector/4;
++ memset(ole2->SSecID, 0xFF, ole2->SSecIDCount * sizeof(DWORD));
+ sector = ole2->sfatstart;
+ wptr=(BYTE*)ole2->SSecID;
+ bytes_left = ole2->SSecIDCount * sizeof(DWORD);
+@@ -828,6 +829,7 @@ static ssize_t read_MSAT(OLE2* ole2, OLE2Header* oleh)
+ total_bytes_read = -1;
+ goto cleanup;
+ }
++ memset(ole2->SecID, 0xFF, ole2->SecIDCount * sizeof(DWORD));
+
+ if ((bytes_read = read_MSAT_header(ole2, oleh, count)) == -1) {
+ total_bytes_read = -1;
diff --git a/158.patch b/158.patch
new file mode 100644
index 0000000..4822dc8
--- /dev/null
+++ b/158.patch
@@ -0,0 +1,88 @@
+From 4052b5415beebe0592fc5e48ae4f60f228d2bf9e Mon Sep 17 00:00:00 2001
+From: pppaulpeter <pppaulpeter@gmail.com>
+Date: Wed, 5 Aug 2026 10:31:08 +0800
+Subject: [PATCH] Fix use of uninitialized memory in read_MSAT (Fixes #155,
+ CVE-2026-26824)
+
+- Add null/count validation in ole2_validate_sector_chain.
+- Stop reading header MSAT sectors upon encountering ENDOFCHAIN or FREESECT.
+- Introduce ole_realloc_zero to zero-fill newly reallocated memory blocks (such as SSAT) and free ptr on allocation failure to prevent memory leaks.
+- Harden blocks * ole->lsector calculation against 32-bit integer wrapping.
+---
+ src/ole.c | 32 +++++++++++++++++++++++++-------
+ 1 file changed, 25 insertions(+), 7 deletions(-)
+
+diff --git a/src/ole.c b/src/ole.c
+index 0442f97..e82201e 100644
+--- a/src/ole.c
++++ b/src/ole.c
+@@ -57,7 +57,6 @@ static size_t sector_pos(OLE2* ole2, DWORD sid);
+ static ssize_t sector_read(OLE2* ole2, void *buffer, size_t buffer_len, DWORD sid);
+ static ssize_t read_MSAT(OLE2* ole2, OLE2Header *oleh);
+ static void *ole_malloc(size_t len);
+-static void *ole_realloc(void *ptr, size_t len);
+
+ static void *ole_malloc(size_t len) {
+ if (len > (1<<24) || len == 0) {
+@@ -66,15 +65,26 @@ static void *ole_malloc(size_t len) {
+ return calloc(1, len);
+ }
+
+-static void *ole_realloc(void *ptr, size_t len) {
+- if (len > (1<<24) || len == 0) {
++/* Reallocates memory and zero-fills only the newly grown region (from old_len to new_len). Frees ptr on failure. */
++static void *ole_realloc_zero(void *ptr, size_t old_len, size_t new_len) {
++ if (new_len > (1<<24) || new_len == 0) {
++ free(ptr);
++ return NULL;
++ }
++ void *new_ptr = realloc(ptr, new_len);
++ if (!new_ptr) {
+ free(ptr);
+ return NULL;
+ }
+- return realloc(ptr, len);
++ if (new_len > old_len) {
++ memset((char *)new_ptr + old_len, 0, new_len - old_len);
++ }
++ return new_ptr;
+ }
+
+ static int ole2_validate_sector_chain(DWORD *chain, DWORD chain_count, DWORD chain_start) {
++ if (chain == NULL || chain_count == 0)
++ return 0;
+ DWORD count = 0;
+ DWORD sector = chain_start;
+ while (sector != ENDOFCHAIN) {
+@@ -535,11 +545,16 @@ static ssize_t ole2_read_body(OLE2 *ole) {
+ size_t bytes_left;
+
+ blocks = (pss->size + (ole->lsector - 1)) / ole->lsector; // count partial
++ if (ole->lsector == 0 || blocks > (1u << 24) / ole->lsector) {
++ total_bytes_read = -1;
++ goto cleanup;
++ }
+ #ifdef OLE_DEBUG
+ fprintf(stderr, "OLE BLOCKS: %d = (%d + (%d - 1))/%d\n",
+ (int)blocks, (int)pss->size, (int)ole->lsector, (int)ole->lsector);
+ #endif
+- if ((ole->SSAT = ole_realloc(ole->SSAT, blocks*ole->lsector)) == NULL) {
++ size_t old_ssat_bytes = ole->SSATCount;
++ if ((ole->SSAT = ole_realloc_zero(ole->SSAT, old_ssat_bytes, blocks*ole->lsector)) == NULL) {
+ total_bytes_read = -1;
+ goto cleanup;
+ }
+@@ -688,8 +703,11 @@ static ssize_t read_MSAT_header(OLE2* ole2, OLE2Header* oleh, DWORD sectorCount)
+
+ for (sectorNum = 0; sectorNum < sectorCount && sectorNum < 109; sectorNum++)
+ {
+- if ((bytes_read = sector_read(ole2, sector, bytes_left, oleh->MSAT[sectorNum])) == -1) {
+- if (xls_debug) fprintf(stderr, "Error: Unable to read sector #%d\n", oleh->MSAT[sectorNum]);
++ DWORD s = oleh->MSAT[sectorNum];
++ if (s == ENDOFCHAIN || s == FREESECT)
++ break;
++ if ((bytes_read = sector_read(ole2, sector, bytes_left, s)) == -1) {
++ if (xls_debug) fprintf(stderr, "Error: Unable to read sector #%d\n", s);
+ return -1;
+ }
+ sector += ole2->lsector;
diff --git a/159.patch b/159.patch
new file mode 100644
index 0000000..086938b
--- /dev/null
+++ b/159.patch
@@ -0,0 +1,79 @@
+From 9ff7bcb2590e2ad7180c443845664a10baee31f7 Mon Sep 17 00:00:00 2001
+From: pppaulpeter <pppaulpeter@gmail.com>
+Date: Wed, 5 Aug 2026 12:09:14 +0800
+Subject: [PATCH] Fix use of uninitialized memory in xls_parseWorkBook (Fixes
+ #154)
+
+- Zero-fill destination buffer at entry of ole2_read to prevent reading uninitialized memory on truncated streams or EOF.
+- Zero-initialize reallocated record buffers in xls_parseWorkBook, xls_preparseWorkSheet, and xls_parseWorkSheet before calling ole2_read.
+---
+ src/ole.c | 3 +++
+ src/xls.c | 15 ++++++++++++---
+ 2 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/src/ole.c b/src/ole.c
+index 0442f97..d140660 100644
+--- a/src/ole.c
++++ b/src/ole.c
+@@ -172,6 +172,9 @@ ssize_t ole2_read(void* buf, size_t size, size_t count, OLE2Stream* olest)
+ size_t totalReadCount;
+
+ totalReadCount=size*count;
++ if (buf && totalReadCount > 0) {
++ memset(buf, 0, totalReadCount);
++ }
+
+ // olest->size inited to -1
+ // printf("===== ole2_read(%ld bytes)\n", totalReadCount);
+diff --git a/src/xls.c b/src/xls.c
+index 7bc7a30..32bc8d9 100644
+--- a/src/xls.c
++++ b/src/xls.c
+@@ -875,11 +875,14 @@ xls_error_t xls_parseWorkBook(xlsWorkBook* pWB)
+ if(xls_debug) xls_showBOF(&bof1);
+
+ if (bof1.size) {
+- if ((buf = realloc(buf, bof1.size)) == NULL) {
++ BYTE *new_buf = realloc(buf, bof1.size);
++ if (new_buf == NULL) {
+ if (xls_debug) fprintf(stderr, "Error: failed to allocate buffer of size %d\n", (int)bof1.size);
+ retval = LIBXLS_ERROR_MALLOC;
+ goto cleanup;
+ }
++ buf = new_buf;
++ memset(buf, 0, bof1.size);
+ if (ole2_read(buf, 1, bof1.size, pWB->olestr) != bof1.size) {
+ if (xls_debug) fprintf(stderr, "Error: failed to read OLE block\n");
+ retval = LIBXLS_ERROR_READ;
+@@ -1120,11 +1123,14 @@ static xls_error_t xls_preparseWorkSheet(xlsWorkSheet* pWS)
+ }
+ xlsConvertBof(&tmp);
+ if (tmp.size) {
+- if ((buf = realloc(buf, tmp.size)) == NULL) {
++ BYTE *new_buf = realloc(buf, tmp.size);
++ if (new_buf == NULL) {
+ if (xls_debug) fprintf(stderr, "Error: failed to allocate buffer of size %d\n", (int)tmp.size);
+ retval = LIBXLS_ERROR_MALLOC;
+ goto cleanup;
+ }
++ buf = new_buf;
++ memset(buf, 0, tmp.size);
+ if((read = ole2_read(buf, 1, tmp.size, pWS->workbook->olestr)) != tmp.size) {
+ if (xls_debug) fprintf(stderr, "Error: failed to read OLE block\n");
+ retval = LIBXLS_ERROR_READ;
+@@ -1293,11 +1299,14 @@ xls_error_t xls_parseWorkSheet(xlsWorkSheet* pWS)
+ }
+ xlsConvertBof((BOF *)&tmp);
+ if (tmp.size) {
+- if ((buf = realloc(buf, tmp.size)) == NULL) {
++ BYTE *new_buf = realloc(buf, tmp.size);
++ if (new_buf == NULL) {
+ if (xls_debug) fprintf(stderr, "Error: failed to allocate buffer of size %d\n", (int)tmp.size);
+ retval = LIBXLS_ERROR_MALLOC;
+ goto cleanup;
+ }
++ buf = new_buf;
++ memset(buf, 0, tmp.size);
+ if((read = ole2_read(buf, 1, tmp.size, pWS->workbook->olestr)) != tmp.size) {
+ if (xls_debug) fprintf(stderr, "Error: failed to read OLE block\n");
+ retval = LIBXLS_ERROR_READ;
diff --git a/libxls.spec b/libxls.spec
index 88e1756..2af9c73 100644
--- a/libxls.spec
+++ b/libxls.spec
@@ -5,7 +5,13 @@ Summary: Read binary Excel files from C/C++
License: BSD-2-Clause
URL: https://github.com/libxls/libxls
-Source0: https://github.com/libxls/libxls/releases/download/v%{version}/%{name}-%{version}.tar.gz
+Source: https://github.com/libxls/libxls/releases/download/v%{version}/%{name}-%{version}.tar.gz
+# Fix CVE-2026-26825
+Patch: https://github.com/libxls/libxls/pull/157.patch
+# Fix CVE-2026-26824
+Patch: https://github.com/libxls/libxls/pull/158.patch
+# Fix use of uninitialized memory in xls_parseWorkBook
+Patch: https://github.com/libxls/libxls/pull/159.patch
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
ExcludeArch: %{ix86}
reply other threads:[~2026-08-15 20:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178682476487.1.446825865215713500.rpms-libxls-fa47cdfd7ff8@fedoraproject.org \
--to=quantum.analyst@gmail.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox