[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1112252: bookworm-pu: package libarchive/3.6.2-1+deb12u3



Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: libarchive@packages.debian.org
Control: affects -1 + src:libarchive
User: release.debian.org@packages.debian.org
Usertags: pu

Fixes four low severity security issues, tests were find and
autopkgtests via debusine also looked good. Debdiff below.

Cheers,
        Moritz

diff -Nru libarchive-3.6.2/debian/changelog libarchive-3.6.2/debian/changelog
--- libarchive-3.6.2/debian/changelog	2024-11-03 13:30:44.000000000 +0100
+++ libarchive-3.6.2/debian/changelog	2025-08-25 22:53:07.000000000 +0200
@@ -1,3 +1,12 @@
+libarchive (3.6.2-1+deb12u3) bookworm; urgency=medium
+
+  * CVE-2025-5914 (Closes: #1107621)
+  * CVE-2025-5915 (Closes: #1107622)
+  * CVE-2025-5916 (Closes: #1107623)
+  * CVE-2025-5917 (Closes: #1107626)
+
+ -- Moritz Mühlenhoff <jmm@debian.org>  Mon, 25 Aug 2025 22:53:07 +0200
+
 libarchive (3.6.2-1+deb12u2) bookworm-security; urgency=high
 
   * Non-maintainer upload by the Security Team.
diff -Nru libarchive-3.6.2/debian/patches/CVE-2025-5914.patch libarchive-3.6.2/debian/patches/CVE-2025-5914.patch
--- libarchive-3.6.2/debian/patches/CVE-2025-5914.patch	1970-01-01 01:00:00.000000000 +0100
+++ libarchive-3.6.2/debian/patches/CVE-2025-5914.patch	2025-08-25 22:50:36.000000000 +0200
@@ -0,0 +1,32 @@
+From 196029dd0a17cd17c916eada9085839032b76ec9 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sat, 10 May 2025 09:34:06 +0200
+Subject: [PATCH] rar: Fix double free with over 4 billion nodes
+
+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.
+
+--- libarchive-3.6.2.orig/libarchive/archive_read_support_format_rar.c
++++ libarchive-3.6.2/libarchive/archive_read_support_format_rar.c
+@@ -335,8 +335,8 @@ struct rar
+   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 @@ archive_read_format_rar_seek_data(struct
+     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.6.2/debian/patches/CVE-2025-5915.patch libarchive-3.6.2/debian/patches/CVE-2025-5915.patch
--- libarchive-3.6.2/debian/patches/CVE-2025-5915.patch	1970-01-01 01:00:00.000000000 +0100
+++ libarchive-3.6.2/debian/patches/CVE-2025-5915.patch	2025-08-25 22:51:18.000000000 +0200
@@ -0,0 +1,177 @@
+From c1d1dcd4b4e746079f60b72676146b6768633868 Mon Sep 17 00:00:00 2001
+From: Tim Kientzle <kientzle@acm.org>
+Date: Sun, 6 Apr 2025 16:44:39 -0700
+Subject: [PATCH 1/4] A test case for Issue #2565.
+
+This just takes the PoC from that issue and wraps
+it into a standard test.
+I've not yet used this to reproduce the issue, much
+less to diagnose the root cause.
+
+--- libarchive-3.6.2.orig/Makefile.am
++++ libarchive-3.6.2/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 \
+--- libarchive-3.6.2.orig/libarchive/archive_read_support_format_rar.c
++++ libarchive-3.6.2/libarchive/archive_read_support_format_rar.c
+@@ -451,7 +451,7 @@ static int read_filter(struct archive_re
+ 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 *
+     }
+ 
+     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 *
+       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 *
+           {
+             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_rea
+   }
+   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);
+   }
+@@ -3236,6 +3236,9 @@ parse_filter(struct archive_read *a, con
+   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;
+--- libarchive-3.6.2.orig/libarchive/test/CMakeLists.txt
++++ libarchive-3.6.2/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
+--- /dev/null
++++ libarchive-3.6.2/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
++++ libarchive-3.6.2/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.6.2/debian/patches/CVE-2025-5916.patch libarchive-3.6.2/debian/patches/CVE-2025-5916.patch
--- libarchive-3.6.2/debian/patches/CVE-2025-5916.patch	1970-01-01 01:00:00.000000000 +0100
+++ libarchive-3.6.2/debian/patches/CVE-2025-5916.patch	2025-08-25 22:51:55.000000000 +0200
@@ -0,0 +1,89 @@
+From bce70c4c26864df2a8d6953e7db6e4b156253508 Mon Sep 17 00:00:00 2001
+From: Tobias Stoeckmann <tobias@stoeckmann.org>
+Date: Sun, 6 Apr 2025 22:56:57 +0200
+Subject: [PATCH] warc: Prevent signed integer overflow
+
+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.
+
+--- libarchive-3.6.2.orig/Makefile.am
++++ libarchive-3.6.2/Makefile.am
+@@ -913,6 +913,7 @@ libarchive_test_EXTRA_DIST=\
+ 	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_zip.zip.uu \
+ 	libarchive/test/test_read_format_zip_7075_utf8_paths.zip.uu \
+ 	libarchive/test/test_read_format_zip_7z_deflate.zip.uu \
+--- libarchive-3.6.2.orig/libarchive/archive_read_support_format_warc.c
++++ libarchive-3.6.2/libarchive/archive_read_support_format_warc.c
+@@ -379,7 +379,8 @@ start_over:
+ 	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);
+@@ -432,7 +433,9 @@ _warc_skip(struct archive_read *a)
+ {
+ 	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);
+--- libarchive-3.6.2.orig/libarchive/test/test_read_format_warc.c
++++ libarchive-3.6.2/libarchive/test/test_read_format_warc.c
+@@ -80,3 +80,27 @@ DEFINE_TEST(test_read_format_warc)
+ 	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
++++ libarchive-3.6.2/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.6.2/debian/patches/CVE-2025-5917.patch libarchive-3.6.2/debian/patches/CVE-2025-5917.patch
--- libarchive-3.6.2/debian/patches/CVE-2025-5917.patch	1970-01-01 01:00:00.000000000 +0100
+++ libarchive-3.6.2/debian/patches/CVE-2025-5917.patch	2025-08-25 22:52:25.000000000 +0200
@@ -0,0 +1,29 @@
+From 14f8dca480161a118360955f8958e1dda05a6aba Mon Sep 17 00:00:00 2001
+From: Brian Campbell <Brian.Campbell@ed.ac.uk>
+Date: Thu, 24 Apr 2025 10:46:40 +0100
+Subject: [PATCH] Fix overflow in build_ustar_entry
+
+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.
+
+--- libarchive-3.6.2.orig/libarchive/archive_write_set_format_pax.c
++++ libarchive-3.6.2/libarchive/archive_write_set_format_pax.c
+@@ -1546,7 +1546,7 @@ build_ustar_entry_name(char *dest, const
+ 	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. */
+@@ -1598,7 +1598,7 @@ build_ustar_entry_name(char *dest, const
+ 	/* 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.6.2/debian/patches/series libarchive-3.6.2/debian/patches/series
--- libarchive-3.6.2/debian/patches/series	2024-11-03 13:30:44.000000000 +0100
+++ libarchive-3.6.2/debian/patches/series	2025-08-25 22:52:13.000000000 +0200
@@ -5,3 +5,7 @@
 fix-OOB-in-rar-delta-filter-2148.patch
 fix-OOB-in-rar-audio-filter-2149.patch
 rar4-reader-protect-copy_from_lzss_window_to_unp-217.patch
+CVE-2025-5914.patch
+CVE-2025-5915.patch
+CVE-2025-5916.patch
+CVE-2025-5917.patch

Reply to: