File CVE-2023-46228.patch of Package zchunk.31132

From 08aec2b4dfd7f709b6e3d511411ffcc83ed4efbe Mon Sep 17 00:00:00 2001
From: Jonathan Dieter <jdieter@gmail.com>
Date: Thu, 5 Oct 2023 19:52:18 +0100
Subject: [PATCH] Handle overflow errors in malformed zchunk files

Thanks to Agostino Sarubbo of Gentoo for the heads up!

Signed-off-by: Jonathan Dieter <jdieter@gmail.com>
---
 src/lib/comp/comp.c      |    6 ++++++
 src/lib/comp/zstd/zstd.c |    6 ++++++
 src/lib/dl/multipart.c   |    6 ++++++
 src/lib/header.c         |   12 ++++++++++++
 4 files changed, 30 insertions(+)

--- a/src/lib/comp/comp.c
+++ b/src/lib/comp/comp.c
@@ -115,6 +115,12 @@ static bool comp_add_to_data(zckCtx *zck
     ALLOCD_BOOL(zck, comp);
     ALLOCD_BOOL(zck, src);
 
+    if((comp->data_size > comp->data_size + src_size) ||
+       (src_size > comp->data_size + src_size)) {
+        zck_log(ZCK_LOG_ERROR, "Integer overflow when reading data");
+        return false;
+    }
+
     comp->data = zrealloc(comp->data, comp->data_size + src_size);
     zck_log(ZCK_LOG_DEBUG, "Adding %lu bytes to compressed buffer",
         src_size);
--- a/src/lib/comp/zstd/zstd.c
+++ b/src/lib/comp/zstd/zstd.c
@@ -92,6 +92,12 @@ static ssize_t compress(zckCtx *zck, zck
     ALLOCD_INT(zck, dst_size);
     ALLOCD_INT(zck, comp);
 
+    if((comp->dc_data_size > comp->dc_data_size + src_size) ||
+       (src_size > comp->dc_data_size + src_size)) {
+        zck_log(ZCK_LOG_ERROR, "Integer overflow when reading decompressed data");
+        return false;
+    }
+
     comp->dc_data = zrealloc(comp->dc_data, comp->dc_data_size + src_size);
 
     memcpy(comp->dc_data + comp->dc_data_size, src, src_size);
--- a/src/lib/dl/multipart.c
+++ b/src/lib/dl/multipart.c
@@ -115,6 +115,12 @@ size_t multipart_extract(zckDL *dl, char
 
     /* Add new data to stored buffer */
     if(mp->buffer) {
+        if((mp->buffer_len > mp->buffer_len + l) ||
+           (l > mp->buffer_len + l)) {
+            zck_log(ZCK_LOG_ERROR, "Integer overflow when extracting multipart data");
+            return 0;
+        }
+
         buf = zrealloc(mp->buffer, mp->buffer_len + l);
         memcpy(buf + mp->buffer_len, b, l);
         l = mp->buffer_len + l;
--- a/src/lib/header.c
+++ b/src/lib/header.c
@@ -59,6 +59,12 @@ static bool read_optional_element(zckCtx
 }
 
 static bool read_header_from_file(zckCtx *zck) {
+    if((zck->lead_size > zck->lead_size + zck->header_length) ||
+       (zck->header_length > zck->lead_size + zck->header_length)) {
+        zck_log(ZCK_LOG_ERROR, "Integer overflow when reading header");
+        return false;
+    }
+
     /* Allocate header and store any extra bytes at beginning of header */
     zck->header = zrealloc(zck->header, zck->lead_size + zck->header_length);
     zck->lead_string = zck->header;
@@ -444,6 +450,12 @@ static bool read_lead(zckCtx *zck) {
     /* Set header digest location */
     zck->hdr_digest_loc = length;
 
+    /* Verify that we're not going to overflow */
+    if(length > length + zck->hash_type.digest_size) {
+        zck_log(ZCK_LOG_ERROR, "Integer overflow when reading lead");
+        return false;
+    }
+
     /* Read header digest */
     zck_log(ZCK_LOG_DEBUG, "Reading header digest");
     header = zrealloc(header, length + zck->hash_type.digest_size);
openSUSE Build Service is sponsored by