diff mbox series

[v2,for,2025.02.x,04/15] package/clamav: add patch for CVE-2026-20213

Message ID 20260902131640.379588-5-titouan.christophe@mind.be
State New
Headers show
Series package/clamav: update to upstream LTS | expand

Commit Message

Titouan Christophe Sept. 2, 2026, 1:16 p.m. UTC
Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
---
 ...ack-triggered-rebuild-pe-overflow-49.patch | 90 +++++++++++++++++++
 package/clamav/clamav.mk                      |  3 +
 2 files changed, 93 insertions(+)
 create mode 100644 package/clamav/0003-libclamav-fix-aspack-triggered-rebuild-pe-overflow-49.patch
diff mbox series

Patch

diff --git a/package/clamav/0003-libclamav-fix-aspack-triggered-rebuild-pe-overflow-49.patch b/package/clamav/0003-libclamav-fix-aspack-triggered-rebuild-pe-overflow-49.patch
new file mode 100644
index 0000000000..beba3f98b1
--- /dev/null
+++ b/package/clamav/0003-libclamav-fix-aspack-triggered-rebuild-pe-overflow-49.patch
@@ -0,0 +1,90 @@ 
+From: "Val S." <valsnyde@cisco.com>
+Date: Tue, 16 Jun 2026 19:37:17 -0400
+Subject: Libclamav: fix Aspack-triggered rebuild PE overflow (#49)
+
+A malformed Aspack sample can force cli_rebuildpe_align() to
+sum rebuilt section sizes in a 32-bit accumulator until the total
+wraps. The rebuilder then allocates a destination buffer that is too
+small and later overflows it while copying section contents.
+
+Fix the allocation math by summing rebuilt section sizes in a 64-bit
+temporary and rejecting outputs whose packed section total or final
+allocation would exceed CLI_MAX_ALLOCATION. This is the correct fix
+because the later memcpy() assumes the destination size is valid; the
+real bug is the earlier integer overflow that under-allocates the
+buffer.
+
+Credit: Trail of Bits, in collaboration with Anthropic
+
+CLAM-2965
+
+---
+Upstream: https://github.com/Cisco-Talos/clamav/commit/5ad56a0ccf13f03e482a0d17fe2c6cb96d8af320
+CVE: CVE-2026-20213
+Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
+---
+ libclamav/rebuildpe.c | 34 ++++++++++++++++++++++++++--------
+ 1 file changed, 26 insertions(+), 8 deletions(-)
+
+diff --git a/libclamav/rebuildpe.c b/libclamav/rebuildpe.c
+index 23f290a990..5692301f15 100644
+--- a/libclamav/rebuildpe.c
++++ b/libclamav/rebuildpe.c
+@@ -50,6 +50,15 @@
+ #define PEALIGN(o, a) (((a)) ? (((o) / (a)) * (a)) : (o))
+ #define PESALIGN(o, a) (((a)) ? (((o) / (a) + ((o) % (a) != 0)) * (a)) : (o))
+ 
++static uint64_t pesalign_u64(uint64_t offset, uint32_t alignment)
++{
++    if (!alignment) {
++        return offset;
++    }
++
++    return ((offset / alignment) + ((offset % alignment) != 0)) * alignment;
++}
++
+ struct IMAGE_PE_HEADER {
+     uint32_t Signature;
+     /* FILE HEADER */
+@@ -127,6 +136,8 @@ int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uin
+ int cli_rebuildpe_align(char *buffer, struct cli_exe_section *sections, int sects, uint32_t base, uint32_t ep, uint32_t ResRva, uint32_t ResSize, int file, uint32_t align)
+ {
+     uint32_t datasize = 0, rawbase = PESALIGN(0x148 + 0x80 + 0x28 * sects, 0x200);
++    uint64_t packed_datasize = 0;
++    uint64_t total_allocation;
+     char *pefile = NULL, *curpe;
+     struct IMAGE_PE_HEADER *fakepe;
+     int i, gotghost = (sections[0].rva > PESALIGN(rawbase, 0x1000));
+@@ -136,17 +147,24 @@ int cli_rebuildpe_align(char *buffer, struct cli_exe_section *sections, int sect
+     if (sects + gotghost > 96)
+         return 0;
+ 
+-    if (!align)
+-        for (i = 0; i < sects; i++)
+-            datasize += PESALIGN(sections[i].rsz, 0x200);
+-    else
+-        for (i = 0; i < sects; i++)
+-            datasize += PESALIGN(PESALIGN(sections[i].rsz, align), 0x200);
++    if (!align) {
++        for (i = 0; i < sects; i++) {
++            packed_datasize += pesalign_u64(sections[i].rsz, 0x200);
++        }
++    } else {
++        for (i = 0; i < sects; i++) {
++            packed_datasize += pesalign_u64(pesalign_u64(sections[i].rsz, align), 0x200);
++        }
++    }
++
++    if (packed_datasize > CLI_MAX_ALLOCATION)
++        return 0;
+ 
+-    if (datasize > CLI_MAX_ALLOCATION)
++    total_allocation = rawbase + packed_datasize;
++    if (total_allocation > CLI_MAX_ALLOCATION)
+         return 0;
+ 
+-    pefile = (char *)cli_max_calloc(rawbase + datasize, 1);
++    pefile = (char *)cli_max_calloc((size_t)total_allocation, 1);
+     if (!pefile)
+         return 0;
+ 
diff --git a/package/clamav/clamav.mk b/package/clamav/clamav.mk
index d97390ca5e..bdb94e7436 100644
--- a/package/clamav/clamav.mk
+++ b/package/clamav/clamav.mk
@@ -30,6 +30,9 @@  CLAMAV_IGNORE_CVES += CVE-2026-20031
 # 0002-libclamav-fix-pespin-cleanup-bitmap-tracking-47.patch
 CLAMAV_IGNORE_CVES += CVE-2026-20217
 
+# 0003-libclamav-fix-aspack-triggered-rebuild-pe-overflow-49.patch
+CLAMAV_IGNORE_CVES += CVE-2026-20213
+
 CLAMAV_DEPENDENCIES = \
 	bzip2 \
 	host-pkgconf \