diff mbox series

[kirkstone] libarchive: Fix CVE-2024-20696

Message ID 20250102074856.29056-1-mail2szahir@gmail.com
State Under Review
Delegated to: Steve Sakoman
Headers show
Series [kirkstone] libarchive: Fix CVE-2024-20696 | expand

Commit Message

aszh07 Jan. 2, 2025, 7:48 a.m. UTC
Add Patch file to fix CVE-2024-20696

CVE: CVE-2024-20696

Signed-off-by: Nitin Wankhade <nitin.wankhade@kpit.com>
Signed-off-by: Nikhil R <nikhilr5@kpit.com>
---
 .../libarchive/CVE-2024-20696.patch           | 114 ++++++++++++++++++
 .../libarchive/libarchive_3.6.2.bb            |   1 +
 2 files changed, 115 insertions(+)
 create mode 100644 meta/recipes-extended/libarchive/libarchive/CVE-2024-20696.patch
diff mbox series

Patch

diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2024-20696.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2024-20696.patch
new file mode 100644
index 0000000000..f980f60597
--- /dev/null
+++ b/meta/recipes-extended/libarchive/libarchive/CVE-2024-20696.patch
@@ -0,0 +1,114 @@ 
+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.
+
+CVE: CVE-2024-20696
+Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/eac15e252010c1189a5c0f461364dbe2cd2a68b1]
+
+Signed-off-by: Nitin Wankhade <nitin.wankhade@kpit.com>
+---
+
+--- a/libarchive/archive_read_support_format_rar.c   2024-12-11 12:33:47.566310000 +0530
++++ a/libarchive/archive_read_support_format_rar.c   2024-12-11 13:09:39.396142151 +0530
+@@ -432,7 +432,7 @@ static int make_table_recurse(struct arc
+                               struct huffman_table_entry *, int, int);
+ static int expand(struct archive_read *, int64_t *);
+ static int copy_from_lzss_window_to_unp(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 *);
+ static int parse_filter(struct archive_read *, const uint8_t *, uint16_t,
+                         uint8_t);
+@@ -2069,7 +2069,7 @@ read_data_compressed(struct archive_read
+         bs = rar->unp_buffer_size - rar->unp_offset;
+       else
+         bs = (size_t)rar->bytes_uncopied;
+-      ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
++      ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
+       if (ret != ARCHIVE_OK)
+         return (ret);
+       rar->offset += bs;
+@@ -2209,7 +2209,7 @@ read_data_compressed(struct archive_read
+       bs = rar->unp_buffer_size - rar->unp_offset;
+     else
+       bs = (size_t)rar->bytes_uncopied;
+-    ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, (int)bs);
++    ret = copy_from_lzss_window_to_unp(a, buff, rar->offset, bs);
+     if (ret != ARCHIVE_OK)
+       return (ret);
+     rar->offset += bs;
+@@ -3090,11 +3090,16 @@ copy_from_lzss_window(struct archive_rea
+ 
+ static int
+ copy_from_lzss_window_to_unp(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)
+@@ -3106,17 +3111,17 @@ copy_from_lzss_window_to_unp(struct arch
+   }
+ 
+   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],
+@@ -3126,9 +3131,7 @@ copy_from_lzss_window_to_unp(struct arch
+              &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)
+@@ -3136,6 +3139,10 @@ copy_from_lzss_window_to_unp(struct arch
+   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 *
diff --git a/meta/recipes-extended/libarchive/libarchive_3.6.2.bb b/meta/recipes-extended/libarchive/libarchive_3.6.2.bb
index e1eca79004..6af01cf408 100644
--- a/meta/recipes-extended/libarchive/libarchive_3.6.2.bb
+++ b/meta/recipes-extended/libarchive/libarchive_3.6.2.bb
@@ -33,6 +33,7 @@  SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \
            file://CVE-2024-26256.patch \
            file://CVE-2024-48957.patch \
            file://CVE-2024-48958.patch \
+           file://CVE-2024-20696.patch \
            "
 UPSTREAM_CHECK_URI = "http://libarchive.org/"