libarchive/libarchive-3.4.3-avoid-stack-overflow.patch
2020-08-21 21:13:31 +08:00

66 lines
2.6 KiB
Diff

From 4e575be32d0d128fa046ca74353d1ac880436948 Mon Sep 17 00:00:00 2001
From: lutianxiong <lutianxiong@huawei.com>
Date: Thu, 20 Aug 2020 19:09:03 +0800
Subject: [PATCH] Add a loop checker in read_data_compressed to avoid stack
overflow.
Signed-off-by: lutianxiong <lutianxiong@huawei.com>
---
libarchive/archive_read_support_format_rar.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
index 98efbb1a6..283a96044 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -151,6 +151,9 @@
#undef minimum
#define minimum(a, b) ((a)<(b)?(a):(b))
+/* Stack overflow check */
+#define MAX_COMPRESS_DEPTH 1024
+
/* Fields common to all headers */
struct rar_header
{
@@ -340,7 +343,7 @@ static int read_symlink_stored(struct archive_read *, struct archive_entry *,
static int read_data_stored(struct archive_read *, const void **, size_t *,
int64_t *);
static int read_data_compressed(struct archive_read *, const void **, size_t *,
- int64_t *);
+ int64_t *, size_t);
static int rar_br_preparation(struct archive_read *, struct rar_br *);
static int parse_codes(struct archive_read *);
static void free_codes(struct archive_read *);
@@ -1026,7 +1029,7 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
case COMPRESS_METHOD_NORMAL:
case COMPRESS_METHOD_GOOD:
case COMPRESS_METHOD_BEST:
- ret = read_data_compressed(a, buff, size, offset);
+ ret = read_data_compressed(a, buff, size, offset, 0);
if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
rar->start_new_table = 1;
@@ -1883,8 +1886,11 @@ read_data_stored(struct archive_read *a, const void **buff, size_t *size,
static int
read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
- int64_t *offset)
+ int64_t *offset, size_t looper)
{
+ if (looper++ > MAX_COMPRESS_DEPTH)
+ return (ARCHIVE_FATAL);
+
struct rar *rar;
int64_t start, end, actualend;
size_t bs;
@@ -1982,7 +1988,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
{
case 0:
rar->start_new_table = 1;
- return read_data_compressed(a, buff, size, offset);
+ return read_data_compressed(a, buff, size, offset, looper);
case 2:
rar->ppmd_eod = 1;/* End Of ppmd Data. */