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