Package: release.debian.org Severity: normal X-Debbugs-Cc: libarchive@packages.debian.org, roam@debian.org Control: affects -1 + src:libarchive User: release.debian.org@packages.debian.org Usertags: unblock Please unblock package libarchive; this is a pre-approval request before I upload the package to unstable. [ Reason ] Apply four patches taken from later upstream releases for security issues tracked by the security team as CVE-2025-5914, CVE-2025-5915, CVE-2025-5916, and CVE-2025-5917. [ Impact ] Programs using libarchive may be tricked into mishandling specific types of archives, with effects ranging from undefined behavior to data disclosure. [ Tests ] Some of the patches also add tests to libarchive's unit test suite. [ Risks ] IMHO low; the fixes have been approved by the upstream authors and included in later libarchive releases. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing unblock libarchive/3.7.4-4
diff -Nru libarchive-3.7.4/debian/changelog libarchive-3.7.4/debian/changelog --- libarchive-3.7.4/debian/changelog 2025-04-27 23:19:29.000000000 +0300 +++ libarchive-3.7.4/debian/changelog 2025-07-24 17:40:32.000000000 +0300 @@ -1,3 +1,11 @@ +libarchive (3.7.4-4) unstable; urgency=medium + + * Add the CVE-2025-5914, CVE-2025-5915, CVE-2025-5916, and + CVE-2025-5917 patches. + Closes: #1107621, #1107622, #1107623, #1107626 + + -- Peter Pentchev <roam@debian.org> Thu, 24 Jul 2025 17:40:32 +0300 + libarchive (3.7.4-3) unstable; urgency=medium * Rename the CVE-2025-1632 patch to CVE-2025-1632-25724, use the exact diff -Nru libarchive-3.7.4/debian/patches/CVE-2025-5914.patch libarchive-3.7.4/debian/patches/CVE-2025-5914.patch --- libarchive-3.7.4/debian/patches/CVE-2025-5914.patch 1970-01-01 02:00:00.000000000 +0200 +++ libarchive-3.7.4/debian/patches/CVE-2025-5914.patch 2025-07-24 16:53:30.000000000 +0300 @@ -0,0 +1,32 @@ +Description: rar: Fix double free with over 4 billion nodes (#2598) + If a system is capable of handling 4 billion nodes in memory, a double + free could occur because of an unsigned integer overflow leading to a + realloc call with size argument of 0. Eventually, the client will + release that memory again, triggering a double free. +Bug-Debian: https://bugs.debian.org/1107621 +Author: Tobias Stoeckmann <tobias@stoeckmann.org> +Origin: upstream, https://github.com/libarchive/libarchive/commit/09685126fcec664e2b8ca595e1fc371bd494d209 +Last-Update: 2025-07-24 + +--- a/libarchive/archive_read_support_format_rar.c ++++ b/libarchive/archive_read_support_format_rar.c +@@ -335,8 +335,8 @@ + int found_first_header; + char has_endarc_header; + struct data_block_offsets *dbo; +- unsigned int cursor; +- unsigned int nodes; ++ size_t cursor; ++ size_t nodes; + char filename_must_match; + + /* LZSS members */ +@@ -1186,7 +1186,7 @@ + int whence) + { + int64_t client_offset, ret; +- unsigned int i; ++ size_t i; + struct rar *rar = (struct rar *)(a->format->data); + + if (rar->compression_method == COMPRESS_METHOD_STORE) diff -Nru libarchive-3.7.4/debian/patches/CVE-2025-5915.patch libarchive-3.7.4/debian/patches/CVE-2025-5915.patch --- libarchive-3.7.4/debian/patches/CVE-2025-5915.patch 1970-01-01 02:00:00.000000000 +0200 +++ libarchive-3.7.4/debian/patches/CVE-2025-5915.patch 2025-07-24 16:54:40.000000000 +0300 @@ -0,0 +1,182 @@ +Description: 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 +Bug-Debian: https://bugs.debian.org/1107622 +Author: Tobias Stoeckmann <tobias@stoeckmann.org> +Origin: upstream, https://github.com/libarchive/libarchive/commit/a612bf62f86a6faa47bd57c52b94849f0a404d8c +Last-Update: 2025-07-24 + +--- a/Makefile.am ++++ b/Makefile.am +@@ -511,6 +511,7 @@ + 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 \ +@@ -870,6 +871,7 @@ + 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 \ +--- a/libarchive/archive_read_support_format_rar.c ++++ b/libarchive/archive_read_support_format_rar.c +@@ -451,7 +451,7 @@ + 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); + +@@ -2903,7 +2903,7 @@ + } + + if ((symbol = read_next_symbol(a, &rar->maincode)) < 0) +- return (ARCHIVE_FATAL); ++ goto bad_data; + + if (symbol < 256) + { +@@ -2930,14 +2930,14 @@ + 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) +@@ -3022,7 +3022,7 @@ + { + if ((lowoffsetsymbol = + read_next_symbol(a, &rar->lowoffsetcode)) < 0) +- return (ARCHIVE_FATAL); ++ goto bad_data; + if(lowoffsetsymbol == 16) + { + rar->numlowoffsetrepeats = 15; +@@ -3070,7 +3070,7 @@ + } + + 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; +@@ -3085,7 +3085,7 @@ + } + 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); + } +@@ -3240,6 +3240,9 @@ + 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; +--- a/libarchive/test/CMakeLists.txt ++++ b/libarchive/test/CMakeLists.txt +@@ -155,6 +155,7 @@ + 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 +--- /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)); ++} +--- /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 diff -Nru libarchive-3.7.4/debian/patches/CVE-2025-5916.patch libarchive-3.7.4/debian/patches/CVE-2025-5916.patch --- libarchive-3.7.4/debian/patches/CVE-2025-5916.patch 1970-01-01 02:00:00.000000000 +0200 +++ libarchive-3.7.4/debian/patches/CVE-2025-5916.patch 2025-07-24 16:54:45.000000000 +0300 @@ -0,0 +1,92 @@ +commit ef093729521fcf73fa4007d5ae77adfe4df42403 +Date: Mon Apr 7 00:24:13 2025 +0200 + +Description: warc: Prevent signed integer overflow (#2568) + If a warc archive claims to have more than INT64_MAX - 4 content bytes, + the inevitable failure to skip all these bytes could lead to parsing + data which should be ignored instead. + . + The test case contains a conversation entry with that many bytes and if + the entry is not properly skipped, the warc implementation would read + the conversation data as a new file entry. +Bug-Debian: https://bugs.debian.org/1107623 +Origin: upstream, https://github.com/libarchive/libarchive/commit/ef093729521fcf73fa4007d5ae77adfe4df42403 +Author: Tobias Stoeckmann <tobias@stoeckmann.org> +Last-Update: 2025-07-24 + +--- a/Makefile.am ++++ b/Makefile.am +@@ -935,6 +935,7 @@ + libarchive/test/test_read_format_ustar_filename_eucjp.tar.Z.uu \ + libarchive/test/test_read_format_ustar_filename_koi8r.tar.Z.uu \ + libarchive/test/test_read_format_warc.warc.uu \ ++ libarchive/test/test_read_format_warc_incomplete.warc.uu \ + libarchive/test/test_read_format_xar_doublelink.xar.uu \ + libarchive/test/test_read_format_zip.zip.uu \ + libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \ +--- a/libarchive/archive_read_support_format_warc.c ++++ b/libarchive/archive_read_support_format_warc.c +@@ -386,7 +386,8 @@ + case LAST_WT: + default: + /* consume the content and start over */ +- _warc_skip(a); ++ if (_warc_skip(a) < 0) ++ return (ARCHIVE_FATAL); + goto start_over; + } + return (ARCHIVE_OK); +@@ -439,7 +440,9 @@ + { + struct warc_s *w = a->format->data; + +- __archive_read_consume(a, w->cntlen + 4U/*\r\n\r\n separator*/); ++ if (__archive_read_consume(a, w->cntlen) < 0 || ++ __archive_read_consume(a, 4U/*\r\n\r\n separator*/) < 0) ++ return (ARCHIVE_FATAL); + w->cntlen = 0U; + w->cntoff = 0U; + return (ARCHIVE_OK); +--- a/libarchive/test/test_read_format_warc.c ++++ b/libarchive/test/test_read_format_warc.c +@@ -78,3 +78,27 @@ + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + } ++ ++DEFINE_TEST(test_read_format_warc_incomplete) ++{ ++ const char reffile[] = "test_read_format_warc_incomplete.warc"; ++ struct archive_entry *ae; ++ struct archive *a; ++ ++ 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, 10240)); ++ ++ /* Entry cannot be parsed */ ++ assertEqualIntA(a, ARCHIVE_FATAL, archive_read_next_header(a, &ae)); ++ ++ /* Verify archive format. */ ++ assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); ++ ++ /* Verify closing and resource freeing */ ++ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); ++ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); ++} +--- /dev/null ++++ b/libarchive/test/test_read_format_warc_incomplete.warc.uu +@@ -0,0 +1,10 @@ ++begin 644 test_read_format_warc_incomplete.warc ++M5T%20R\Q+C`-"E=!4D,M5'EP93H@8V]N=F5R<VEO;@T*5T%20RU$871E.B`R ++M,#(U+3`S+3,P5#$U.C`P.C0P6@T*0V]N=&5N="U,96YG=&@Z(#DR,C,S-S(P ++M,S8X-30W-S4X,#<-"@T*5T%20R\Q+C`-"E=!4D,M5'EP93H@<F5S;W5R8V4- ++M"E=!4D,M5&%R9V5T+55223H@9FEL93HO+W)E861M92YT>'0-"E=!4D,M1&%T ++M93H@,C`R-2TP,RTS,%0Q-3HP,#HT,%H-"D-O;G1E;G0M5'EP93H@=&5X="]P ++M;&%I;@T*0V]N=&5N="U,96YG=&@Z(#,X#0H-"E1H92!R96%D;64N='AT('-H ++4;W5L9"!N;W0@8F4@=FES:6)L90H` ++` ++end diff -Nru libarchive-3.7.4/debian/patches/CVE-2025-5917.patch libarchive-3.7.4/debian/patches/CVE-2025-5917.patch --- libarchive-3.7.4/debian/patches/CVE-2025-5917.patch 1970-01-01 02:00:00.000000000 +0200 +++ libarchive-3.7.4/debian/patches/CVE-2025-5917.patch 2025-07-24 16:45:18.000000000 +0300 @@ -0,0 +1,40 @@ +Description: Fix overflow in build_ustar_entry (#2588) + The calculations for the suffix and prefix can increment the endpoint + for a trailing slash. Hence the limits used should be one lower than the + maximum number of bytes. + . + Without this patch, when this happens for both the prefix and the + suffix, we end up with 156 + 100 bytes, and the write of the null at the + end will overflow the 256 byte buffer. This can be reproduced by running + ``` + mkdir -p foo/bar + bsdtar cvf test.tar foo////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////bar + ``` + when bsdtar is compiled with Address Sanitiser, although I originally + noticed this by accident with a genuine filename on a CHERI capability + system, which faults immediately on the buffer overflow. +Bug-Debian: https://bugs.debian.org/1107626 +Author: Brian Campbell <Brian.Campbell@ed.ac.uk> +Origin: upstream, https://github.com/libarchive/libarchive/commit/7c02cde37a63580cd1859183fbbd2cf04a89be85 +Last-Update: 2025-07-24 + +--- a/libarchive/archive_write_set_format_pax.c ++++ b/libarchive/archive_write_set_format_pax.c +@@ -1555,7 +1555,7 @@ + const char *filename, *filename_end; + char *p; + int need_slash = 0; /* Was there a trailing slash? */ +- size_t suffix_length = 99; ++ size_t suffix_length = 98; /* 99 - 1 for trailing slash */ + size_t insert_length; + + /* Length of additional dir element to be added. */ +@@ -1607,7 +1607,7 @@ + /* Step 2: Locate the "prefix" section of the dirname, including + * trailing '/'. */ + prefix = src; +- prefix_end = prefix + 155; ++ prefix_end = prefix + 154 /* 155 - 1 for trailing / */; + if (prefix_end > filename) + prefix_end = filename; + while (prefix_end > prefix && *prefix_end != '/') diff -Nru libarchive-3.7.4/debian/patches/series libarchive-3.7.4/debian/patches/series --- libarchive-3.7.4/debian/patches/series 2025-04-27 23:12:26.000000000 +0300 +++ libarchive-3.7.4/debian/patches/series 2025-07-24 16:55:24.000000000 +0300 @@ -3,3 +3,7 @@ fix-OOB-in-rar-audio-filter-2149.patch rar4-reader-protect-copy_from_lzss_window_to_unp-217.patch CVE-2025-1632-25724.patch +CVE-2025-5914.patch +CVE-2025-5915.patch +CVE-2025-5916.patch +CVE-2025-5917.patch
Attachment:
signature.asc
Description: PGP signature