Commit 83c3d6880 for clamav.net

commit 83c3d68805bc397633582a64cd85d2008b85468f
Author: Val S. <valsnyde@cisco.com>
Date:   Wed May 20 20:10:24 2026 -0400

    Libclamav: harden XLM drawing group length checks (#1707)

    The XLM drawing group parser grew a size_t length with BIFF record
    sizes before reallocating and copying the new chunk. That pattern
    looked like an integer overflow candidate, but the reported heap
    overflow is not reachable in practice because every growth step is
    immediately bounded by cli_max_realloc() and the BIFF record length
    cap, so the accumulated length cannot approach SIZE_MAX before the
    allocation limit stops processing.

    Add explicit pre-addition overflow checks at the two drawing group
    growth sites anyway. This keeps the existing control flow while
    making the arithmetic safety guarantee explicit and easier to audit.

    Credit: rinto

    CLAM-2935

diff --git a/libclamav/xlm_extract.c b/libclamav/xlm_extract.c
index 71f660602..f424184a4 100644
--- a/libclamav/xlm_extract.c
+++ b/libclamav/xlm_extract.c
@@ -29,6 +29,7 @@

 #include <fcntl.h>
 #include <stdbool.h>
+#include <stdint.h>

 #include "fmap.h"
 #include "entconv.h"
@@ -4791,6 +4792,11 @@ cl_error_t cli_extract_xlm_macros_and_images(const char *dir, cli_ctx *ctx, char

                 } else {
                     /* already found the beginning of a drawing group, extract the remaining chunks */
+                    if (drawinggroup_len > SIZE_MAX - biff_header.length) {
+                        cli_dbgmsg("[cli_extract_xlm_macros_and_images] Drawing group length overflow\n");
+                        status = CL_EFORMAT;
+                        goto done;
+                    }
                     drawinggroup_len += biff_header.length;
                     CLI_MAX_REALLOC_OR_GOTO_DONE(drawinggroup, drawinggroup_len, status = CL_EMEM);
                     memcpy(drawinggroup + (drawinggroup_len - biff_header.length), data, biff_header.length);
@@ -4802,6 +4808,11 @@ cl_error_t cli_extract_xlm_macros_and_images(const char *dir, cli_ctx *ctx, char
                 if ((OPC_MSODRAWINGGROUP == previous_biff8_opcode) &&
                     (NULL != drawinggroup)) {
                     /* already found the beginning of an image, extract the remaining chunks */
+                    if (drawinggroup_len > SIZE_MAX - biff_header.length) {
+                        cli_dbgmsg("[cli_extract_xlm_macros_and_images] Drawing group length overflow\n");
+                        status = CL_EFORMAT;
+                        goto done;
+                    }
                     drawinggroup_len += biff_header.length;
                     CLI_MAX_REALLOC_OR_GOTO_DONE(drawinggroup, drawinggroup_len, status = CL_EMEM);
                     memcpy(drawinggroup + (drawinggroup_len - biff_header.length), data, biff_header.length);