From: Divya Chellam Date: Tue, 8 Jul 2025 09:38:16 +0000 (+0530) Subject: libarchive: fix CVE-2025-5915 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41e7be4aa28481530d5e259d0f25b238b86c012d;p=thirdparty%2Fopenembedded%2Fopenembedded-core-contrib.git libarchive: fix CVE-2025-5915 A vulnerability has been identified in the libarchive library. This flaw can lead to a heap b uffer over-read due to the size of a filter block potentially exceeding the Lempel-Ziv-Storer -Schieber (LZSS) window. This means the library may attempt to read beyond the allocated memo ry buffer, which can result in unpredictable program behavior, crashes (denial of service), o r the disclosure of sensitive information from adjacent memory regions. Reference: https://security-tracker.debian.org/tracker/CVE-2025-5915 Upstream-patches: https://github.com/libarchive/libarchive/commit/a612bf62f86a6faa47bd57c52b94849f0a404d8c Signed-off-by: Divya Chellam Signed-off-by: Steve Sakoman --- diff --git a/meta/recipes-extended/libarchive/libarchive/CVE-2025-5915.patch b/meta/recipes-extended/libarchive/libarchive/CVE-2025-5915.patch new file mode 100644 index 0000000000..c83f4f1abc --- /dev/null +++ b/meta/recipes-extended/libarchive/libarchive/CVE-2025-5915.patch @@ -0,0 +1,217 @@ +From a612bf62f86a6faa47bd57c52b94849f0a404d8c Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +Date: Sun, 11 May 2025 19:00:11 +0200 +Subject: [PATCH] rar: Fix heap-buffer-overflow (#2599) + +A filter block size must not be larger than the lzss window, which is +defined +by dictionary size, which in turn can be derived from unpacked file +size. + +While at it, improve error messages and fix lzss window wrap around +logic. + +Fixes https://github.com/libarchive/libarchive/issues/2565 + +--------- + +Signed-off-by: Tobias Stoeckmann +Co-authored-by: Tim Kientzle + +CVE: CVE-2025-5915 + +Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/a612bf62f86a6faa47bd57c52b94849f0a404d8c] + +Signed-off-by: Divya Chellam +--- + Makefile.am | 2 + + libarchive/archive_read_support_format_rar.c | 17 ++++--- + libarchive/test/CMakeLists.txt | 1 + + .../test/test_read_format_rar_overflow.c | 48 +++++++++++++++++++ + .../test/test_read_format_rar_overflow.rar.uu | 11 +++++ + 5 files changed, 72 insertions(+), 7 deletions(-) + create mode 100644 libarchive/test/test_read_format_rar_overflow.c + create mode 100644 libarchive/test/test_read_format_rar_overflow.rar.uu + +diff --git a/Makefile.am b/Makefile.am +index 3fd2fdb..e486a8d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -505,6 +505,7 @@ libarchive_test_SOURCES= \ + libarchive/test/test_read_format_rar_encryption_header.c \ + libarchive/test/test_read_format_rar_filter.c \ + libarchive/test/test_read_format_rar_invalid1.c \ ++ libarchive/test/test_read_format_rar_overflow.c \ + libarchive/test/test_read_format_rar5.c \ + libarchive/test/test_read_format_raw.c \ + libarchive/test/test_read_format_tar.c \ +@@ -848,6 +849,7 @@ libarchive_test_EXTRA_DIST=\ + libarchive/test/test_read_format_rar_multivolume.part0003.rar.uu \ + libarchive/test/test_read_format_rar_multivolume.part0004.rar.uu \ + libarchive/test/test_read_format_rar_noeof.rar.uu \ ++ libarchive/test/test_read_format_rar_overflow.rar.uu \ + libarchive/test/test_read_format_rar_ppmd_lzss_conversion.rar.uu \ + libarchive/test/test_read_format_rar_ppmd_use_after_free.rar.uu \ + libarchive/test/test_read_format_rar_ppmd_use_after_free2.rar.uu \ +diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c +index 091a993..4d3b966 100644 +--- a/libarchive/archive_read_support_format_rar.c ++++ b/libarchive/archive_read_support_format_rar.c +@@ -451,7 +451,7 @@ static int read_filter(struct archive_read *, int64_t *); + static int rar_decode_byte(struct archive_read*, uint8_t *); + static int execute_filter(struct archive_read*, struct rar_filter *, + struct rar_virtual_machine *, size_t); +-static int copy_from_lzss_window(struct archive_read *, void *, int64_t, int); ++static int copy_from_lzss_window(struct archive_read *, uint8_t *, int64_t, int); + static inline void vm_write_32(struct rar_virtual_machine*, size_t, uint32_t); + static inline uint32_t vm_read_32(struct rar_virtual_machine*, size_t); + +@@ -2899,7 +2899,7 @@ expand(struct archive_read *a, int64_t *end) + } + + if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) +- return (ARCHIVE_FATAL); ++ goto bad_data; + + if (symbol < 256) + { +@@ -2926,14 +2926,14 @@ expand(struct archive_read *a, int64_t *end) + else + { + if (parse_codes(a) != ARCHIVE_OK) +- return (ARCHIVE_FATAL); ++ goto bad_data; + continue; + } + } + else if(symbol==257) + { + if (!read_filter(a, end)) +- return (ARCHIVE_FATAL); ++ goto bad_data; + continue; + } + else if(symbol==258) +@@ -3018,7 +3018,7 @@ expand(struct archive_read *a, int64_t *end) + { + if ((lowoffsetsymbol = + read_next_symbol(a, &rar->lowoffsetcode)) < 0) +- return (ARCHIVE_FATAL); ++ goto bad_data; + if(lowoffsetsymbol == 16) + { + rar->numlowoffsetrepeats = 15; +@@ -3066,7 +3066,7 @@ bad_data: + } + + static int +-copy_from_lzss_window(struct archive_read *a, void *buffer, ++copy_from_lzss_window(struct archive_read *a, uint8_t *buffer, + int64_t startpos, int length) + { + int windowoffs, firstpart; +@@ -3081,7 +3081,7 @@ copy_from_lzss_window(struct archive_read *a, void *buffer, + } + if (firstpart < length) { + memcpy(buffer, &rar->lzss.window[windowoffs], firstpart); +- memcpy(buffer, &rar->lzss.window[0], length - firstpart); ++ memcpy(buffer + firstpart, &rar->lzss.window[0], length - firstpart); + } else { + memcpy(buffer, &rar->lzss.window[windowoffs], length); + } +@@ -3228,6 +3228,9 @@ parse_filter(struct archive_read *a, const uint8_t *bytes, uint16_t length, uint + else + blocklength = prog ? prog->oldfilterlength : 0; + ++ if (blocklength > rar->dictionary_size) ++ return 0; ++ + registers[3] = PROGRAM_SYSTEM_GLOBAL_ADDRESS; + registers[4] = blocklength; + registers[5] = prog ? prog->usagecount : 0; +diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt +index bbbff22..05c6fd7 100644 +--- a/libarchive/test/CMakeLists.txt ++++ b/libarchive/test/CMakeLists.txt +@@ -154,6 +154,7 @@ IF(ENABLE_TEST) + test_read_format_rar_encryption_partially.c + test_read_format_rar_invalid1.c + test_read_format_rar_filter.c ++ test_read_format_rar_overflow.c + test_read_format_rar5.c + test_read_format_raw.c + test_read_format_tar.c +diff --git a/libarchive/test/test_read_format_rar_overflow.c b/libarchive/test/test_read_format_rar_overflow.c +new file mode 100644 +index 0000000..b39ed6b +--- /dev/null ++++ b/libarchive/test/test_read_format_rar_overflow.c +@@ -0,0 +1,48 @@ ++/*- ++ * Copyright (c) 2003-2025 Tim Kientzle ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR ++ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ++ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#include "test.h" ++ ++DEFINE_TEST(test_read_format_rar_overflow) ++{ ++ struct archive *a; ++ struct archive_entry *ae; ++ const char reffile[] = "test_read_format_rar_overflow.rar"; ++ const void *buff; ++ size_t size; ++ int64_t offset; ++ ++ extract_reference_file(reffile); ++ assert((a = archive_read_new()) != NULL); ++ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); ++ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); ++ assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, reffile, 1024)); ++ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); ++ assertEqualInt(48, archive_entry_size(ae)); ++ /* The next call should reproduce Issue #2565 */ ++ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data_block(a, &buff, &size, &offset)); ++ ++ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); ++ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); ++} +diff --git a/libarchive/test/test_read_format_rar_overflow.rar.uu b/libarchive/test/test_read_format_rar_overflow.rar.uu +new file mode 100644 +index 0000000..48fd3fd +--- /dev/null ++++ b/libarchive/test/test_read_format_rar_overflow.rar.uu +@@ -0,0 +1,11 @@ ++begin 644 test_read_format_rar_overflow.rar ++M4F%R(1H'`,($=```(0`@`0``,`````(````````````S`0``````,`"_B%_: ++MZ?^[:7``?S!!,`@P,KB@,T@RN33)MTEB@5Z3<`DP`K35`.0P63@P<,Q&0?#, ++MA##,,",S,(@P,#,@##`&,#":(3`!,#"(`9HPS,,S13`P,#`P,*`PHPS,,S1A ++M,!,!,#","9H@S12D#$PP!C`P`*'F03":,,T8H`@\,/DPJS!/,"30,#`3N%LP ++MCQ6:S3"!,#LP22<-,$5%B"5B$S!)(&*>G#+@!`E`%0ODC])62=DO,)BYJX'P ++M=/LPZ3!!008?%S`P,#`P,#`P,#`P,#`P,#`P,#`P2$PP,#`P03!(,#`P,#`& ++M,`7),#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P,#`P ++-,#`P,#`P,#`P,#`P,``` ++` ++end +-- +2.40.0 + diff --git a/meta/recipes-extended/libarchive/libarchive_3.6.2.bb b/meta/recipes-extended/libarchive/libarchive_3.6.2.bb index 4d0e3f7179..c612c1b7e0 100644 --- a/meta/recipes-extended/libarchive/libarchive_3.6.2.bb +++ b/meta/recipes-extended/libarchive/libarchive_3.6.2.bb @@ -36,6 +36,7 @@ SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \ file://CVE-2024-20696.patch \ file://CVE-2025-25724.patch \ file://CVE-2025-5914.patch \ + file://CVE-2025-5915.patch \ " UPSTREAM_CHECK_URI = "http://libarchive.org/"