package/clamav: add patch for CVE-2026-20213

Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be>
This commit is contained in:
Titouan Christophe
2026-09-02 15:16:29 +02:00
committed by Raphaël Mélotte
parent 83c2d9e1ef
commit b032ee0c60
2 changed files with 93 additions and 0 deletions

View File

@@ -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;

View File

@@ -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 \