!61 fix CVE-2024-20696
From: @ultra_planet Reviewed-by: @dillon_chen Signed-off-by: @dillon_chen
This commit is contained in:
commit
5888a5ff2b
119
backport-CVE-2024-20696.patch
Normal file
119
backport-CVE-2024-20696.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
From eac15e252010c1189a5c0f461364dbe2cd2a68b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Dustin L. Howett" <dustin@howett.net>
|
||||||
|
Date: Thu, 9 May 2024 18:59:17 -0500
|
||||||
|
Subject: [PATCH] rar4 reader: protect copy_from_lzss_window_to_unp() (#2172)
|
||||||
|
|
||||||
|
copy_from_lzss_window_to_unp unnecessarily took an `int` parameter where
|
||||||
|
both of its callers were holding a `size_t`.
|
||||||
|
|
||||||
|
A lzss opcode chain could be constructed that resulted in a negative
|
||||||
|
copy length, which when passed into memcpy would result in a very, very
|
||||||
|
large positive number.
|
||||||
|
|
||||||
|
Switching copy_from_lzss_window_to_unp to take a `size_t` allows it to
|
||||||
|
properly bounds-check length.
|
||||||
|
|
||||||
|
In addition, this patch also ensures that `length` is not itself larger
|
||||||
|
than the destination buffer.
|
||||||
|
|
||||||
|
Security: CVE-2024-20696
|
||||||
|
|
||||||
|
Reference:https://github.com/libarchive/libarchive/commit/eac15e252010c1189a5c0f461364dbe2cd2a68b1
|
||||||
|
Conflict:copy_from_lzss_window_to_unp() -> copy_from_lzss_window();adapt context
|
||||||
|
---
|
||||||
|
libarchive/archive_read_support_format_rar.c | 28 +++++++++++++-------
|
||||||
|
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
||||||
|
index c2666b2..512f5a6 100644
|
||||||
|
--- a/libarchive/archive_read_support_format_rar.c
|
||||||
|
+++ b/libarchive/archive_read_support_format_rar.c
|
||||||
|
@@ -358,7 +358,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
|
||||||
|
struct huffman_table_entry *, int, int);
|
||||||
|
static int64_t expand(struct archive_read *, int64_t);
|
||||||
|
static int copy_from_lzss_window(struct archive_read *, const void **,
|
||||||
|
- int64_t, int);
|
||||||
|
+ int64_t, size_t);
|
||||||
|
static const void *rar_read_ahead(struct archive_read *, size_t, ssize_t *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1936,7 +1936,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||||
|
bs = rar->unp_buffer_size - rar->unp_offset;
|
||||||
|
else
|
||||||
|
bs = (size_t)rar->bytes_uncopied;
|
||||||
|
- ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs);
|
||||||
|
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
|
||||||
|
if (ret != ARCHIVE_OK)
|
||||||
|
return (ret);
|
||||||
|
rar->offset += bs;
|
||||||
|
@@ -2065,7 +2065,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||||
|
bs = rar->unp_buffer_size - rar->unp_offset;
|
||||||
|
else
|
||||||
|
bs = (size_t)rar->bytes_uncopied;
|
||||||
|
- ret = copy_from_lzss_window(a, buff, rar->offset, (int)bs);
|
||||||
|
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
|
||||||
|
if (ret != ARCHIVE_OK)
|
||||||
|
return (ret);
|
||||||
|
rar->offset += bs;
|
||||||
|
@@ -2923,11 +2923,16 @@ bad_data:
|
||||||
|
|
||||||
|
static int
|
||||||
|
copy_from_lzss_window(struct archive_read *a, const void **buffer,
|
||||||
|
- int64_t startpos, int length)
|
||||||
|
+ int64_t startpos, size_t length)
|
||||||
|
{
|
||||||
|
int windowoffs, firstpart;
|
||||||
|
struct rar *rar = (struct rar *)(a->format->data);
|
||||||
|
|
||||||
|
+ if (length > rar->unp_buffer_size)
|
||||||
|
+ {
|
||||||
|
+ goto fatal;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (!rar->unp_buffer)
|
||||||
|
{
|
||||||
|
if ((rar->unp_buffer = malloc(rar->unp_buffer_size)) == NULL)
|
||||||
|
@@ -2939,17 +2944,17 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
windowoffs = lzss_offset_for_position(&rar->lzss, startpos);
|
||||||
|
- if(windowoffs + length <= lzss_size(&rar->lzss)) {
|
||||||
|
+ if(windowoffs + length <= (size_t)lzss_size(&rar->lzss)) {
|
||||||
|
memcpy(&rar->unp_buffer[rar->unp_offset], &rar->lzss.window[windowoffs],
|
||||||
|
length);
|
||||||
|
- } else if (length <= lzss_size(&rar->lzss)) {
|
||||||
|
+ } else if (length <= (size_t)lzss_size(&rar->lzss)) {
|
||||||
|
firstpart = lzss_size(&rar->lzss) - windowoffs;
|
||||||
|
if (firstpart < 0) {
|
||||||
|
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
"Bad RAR file data");
|
||||||
|
return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
- if (firstpart < length) {
|
||||||
|
+ if ((size_t)firstpart < length) {
|
||||||
|
memcpy(&rar->unp_buffer[rar->unp_offset],
|
||||||
|
&rar->lzss.window[windowoffs], firstpart);
|
||||||
|
memcpy(&rar->unp_buffer[rar->unp_offset + firstpart],
|
||||||
|
@@ -2959,9 +2964,7 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
|
||||||
|
&rar->lzss.window[windowoffs], length);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
- "Bad RAR file data");
|
||||||
|
- return (ARCHIVE_FATAL);
|
||||||
|
+ goto fatal;
|
||||||
|
}
|
||||||
|
rar->unp_offset += length;
|
||||||
|
if (rar->unp_offset >= rar->unp_buffer_size)
|
||||||
|
@@ -2969,6 +2972,11 @@ copy_from_lzss_window(struct archive_read *a, const void **buffer,
|
||||||
|
else
|
||||||
|
*buffer = NULL;
|
||||||
|
return (ARCHIVE_OK);
|
||||||
|
+
|
||||||
|
+fatal:
|
||||||
|
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||||
|
+ "Bad RAR file data");
|
||||||
|
+ return (ARCHIVE_FATAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const void *
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: libarchive
|
Name: libarchive
|
||||||
Version: 3.5.2
|
Version: 3.5.2
|
||||||
Release: 6
|
Release: 7
|
||||||
Summary: Multi-format archive and compression library
|
Summary: Multi-format archive and compression library
|
||||||
|
|
||||||
License: BSD
|
License: BSD
|
||||||
@ -19,6 +19,7 @@ Patch6002: backport-0002-CVE-2021-36976.patch
|
|||||||
Patch6003: backport-CVE-2021-31566.patch
|
Patch6003: backport-CVE-2021-31566.patch
|
||||||
Patch6004: backport-CVE-2022-26280.patch
|
Patch6004: backport-CVE-2022-26280.patch
|
||||||
Patch6005: backport-CVE-2022-36227.patch
|
Patch6005: backport-CVE-2022-36227.patch
|
||||||
|
Patch6006: backport-CVE-2024-20696.patch
|
||||||
|
|
||||||
Patch9000: libarchive-uninitialized-value.patch
|
Patch9000: libarchive-uninitialized-value.patch
|
||||||
|
|
||||||
@ -193,6 +194,12 @@ run_testsuite
|
|||||||
%{_bindir}/bsdcat
|
%{_bindir}/bsdcat
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jun 06 2024 lingsheng <lingsheng1@h-partners.com> - 3.5.2-7
|
||||||
|
- Type:CVE
|
||||||
|
- ID:CVE-2024-20696
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:fix CVE-2024-20696
|
||||||
|
|
||||||
* Thu Mar 02 2023 zhangpan <zhangpan103@h-paetners.com> - 3.5.2-6
|
* Thu Mar 02 2023 zhangpan <zhangpan103@h-paetners.com> - 3.5.2-6
|
||||||
- fix CVE-2021-36976 patch
|
- fix CVE-2021-36976 patch
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user