public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/libxls] f43: Backport CVE patches
@ 2026-08-15 20:13 Elliott Sales de Andrade
  0 siblings, 0 replies; only message in thread
From: Elliott Sales de Andrade @ 2026-08-15 20:13 UTC (permalink / raw)
  To: git-commits

            A new commit has been pushed.

            Repo   : rpms/libxls
            Branch : f43
            Commit : 7479616cb626c17b345c10efbe82388b9d7d74a7
            Author : Elliott Sales de Andrade <quantum.analyst@gmail.com>
            Date   : 2026-08-15T16:12:58-04:00
            Stats  : +234/-1 in 4 file(s)
            URL    : https://src.fedoraproject.org/rpms/libxls/c/7479616cb626c17b345c10efbe82388b9d7d74a7?branch=f43

            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 d8d9b4a..229ce26 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
 
 BuildRequires:  gcc-c++
 BuildRequires:  make

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-08-15 20:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-08-15 20:13 [rpms/libxls] f43: Backport CVE patches Elliott Sales de Andrade

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox