Complete Yocto mirror with license table for TQMa6UL (2038-compliance)
- 264 license table entries with exact download URLs (224/264 resolved) - Complete sources/ directory with all BitBake recipes - Build configuration: tqma6ul-multi-mba6ulx, spaetzle (musl) - Full traceability for Softwarefreigabeantrag - GCC 13.4.0, Linux 6.6.102, U-Boot 2023.04, musl 1.2.4 - License distribution: GPL-2.0 (24), MIT (23), GPL-2.0+ (18), BSD-3 (16)
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
From 09685126fcec664e2b8ca595e1fc371bd494d209 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
|
||||
Date: Sun, 11 May 2025 02:17:19 +0200
|
||||
Subject: [PATCH] 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.
|
||||
|
||||
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
|
||||
CVE: CVE-2025-5914
|
||||
|
||||
Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/09685126fcec664e2b8ca595e1fc371bd494d209]
|
||||
|
||||
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
||||
---
|
||||
libarchive/archive_read_support_format_rar.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
||||
index 9d155c6..9eb3c84 100644
|
||||
--- a/libarchive/archive_read_support_format_rar.c
|
||||
+++ b/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 archive_read *a, int64_t offset,
|
||||
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)
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
From a612bf62f86a6faa47bd57c52b94849f0a404d8c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
|
||||
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 <tobias@stoeckmann.org>
|
||||
Co-authored-by: Tim Kientzle <kientzle@acm.org>
|
||||
|
||||
CVE: CVE-2025-5915
|
||||
|
||||
Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/a612bf62f86a6faa47bd57c52b94849f0a404d8c]
|
||||
|
||||
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
||||
---
|
||||
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 4fafc41..9f3a6d1 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -519,6 +519,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 \
|
||||
@@ -889,6 +890,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 9eb3c84..88eab62 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);
|
||||
|
||||
@@ -2929,7 +2929,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)
|
||||
{
|
||||
@@ -2956,14 +2956,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)
|
||||
@@ -3048,7 +3048,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;
|
||||
@@ -3096,7 +3096,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;
|
||||
@@ -3111,7 +3111,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);
|
||||
}
|
||||
@@ -3266,6 +3266,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 5d7a5d2..59c5f5d 100644
|
||||
--- a/libarchive/test/CMakeLists.txt
|
||||
+++ b/libarchive/test/CMakeLists.txt
|
||||
@@ -163,6 +163,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
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
From ef093729521fcf73fa4007d5ae77adfe4df42403 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
|
||||
Date: Mon, 7 Apr 2025 00:24:13 +0200
|
||||
Subject: [PATCH] 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.
|
||||
|
||||
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
|
||||
CVE: CVE-2025-5916
|
||||
|
||||
Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/ef093729521fcf73fa4007d5ae77adfe4df42403]
|
||||
|
||||
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
||||
---
|
||||
Makefile.am | 1 +
|
||||
libarchive/archive_read_support_format_warc.c | 7 ++++--
|
||||
libarchive/test/test_read_format_warc.c | 24 +++++++++++++++++++
|
||||
.../test_read_format_warc_incomplete.warc.uu | 10 ++++++++
|
||||
4 files changed, 40 insertions(+), 2 deletions(-)
|
||||
create mode 100644 libarchive/test/test_read_format_warc_incomplete.warc.uu
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 9f3a6d1..7627ec5 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -964,6 +964,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_xar_doublelink.xar.uu \
|
||||
libarchive/test/test_read_format_xar_duplicate_filename_node.xar.uu \
|
||||
libarchive/test/test_read_format_zip.zip.uu \
|
||||
diff --git a/libarchive/archive_read_support_format_warc.c b/libarchive/archive_read_support_format_warc.c
|
||||
index fcec5bc..696f959 100644
|
||||
--- a/libarchive/archive_read_support_format_warc.c
|
||||
+++ b/libarchive/archive_read_support_format_warc.c
|
||||
@@ -386,7 +386,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);
|
||||
@@ -439,7 +440,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);
|
||||
diff --git a/libarchive/test/test_read_format_warc.c b/libarchive/test/test_read_format_warc.c
|
||||
index 91e6dc6..745aabf 100644
|
||||
--- a/libarchive/test/test_read_format_warc.c
|
||||
+++ b/libarchive/test/test_read_format_warc.c
|
||||
@@ -78,3 +78,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));
|
||||
+}
|
||||
diff --git a/libarchive/test/test_read_format_warc_incomplete.warc.uu b/libarchive/test/test_read_format_warc_incomplete.warc.uu
|
||||
new file mode 100644
|
||||
index 0000000..b91b97e
|
||||
--- /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
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 7c02cde37a63580cd1859183fbbd2cf04a89be85 Mon Sep 17 00:00:00 2001
|
||||
From: Brian Campbell <Brian.Campbell@ed.ac.uk>
|
||||
Date: Sat, 26 Apr 2025 05:11:19 +0100
|
||||
Subject: [PATCH] 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.
|
||||
|
||||
CVE: CVE-2025-5917
|
||||
|
||||
Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/7c02cde37a63580cd1859183fbbd2cf04a89be85]
|
||||
|
||||
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
||||
---
|
||||
libarchive/archive_write_set_format_pax.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
|
||||
index 6e35f70..b2ba959 100644
|
||||
--- a/libarchive/archive_write_set_format_pax.c
|
||||
+++ b/libarchive/archive_write_set_format_pax.c
|
||||
@@ -1571,7 +1571,7 @@ build_ustar_entry_name(char *dest, const char *src, size_t src_length,
|
||||
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. */
|
||||
@@ -1623,7 +1623,7 @@ build_ustar_entry_name(char *dest, const char *src, size_t src_length,
|
||||
/* 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 != '/')
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
From 89b8c35ff4b5addc08a85bf5df02b407f8af1f6c Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
|
||||
Date: Sun, 6 Apr 2025 22:34:37 +0200
|
||||
Subject: [PATCH] Improve lseek handling (#2564)
|
||||
|
||||
The skip functions are limited to 1 GB for cases in which libarchive
|
||||
runs on a system with an off_t or long with 32 bits. This has negative
|
||||
impact on 64 bit systems.
|
||||
|
||||
Instead, make sure that _all_ subsequent functions truncate properly.
|
||||
Some of them already did and some had regressions for over 10 years.
|
||||
|
||||
Tests pass on Debian 12 i686 configured with --disable-largefile, i.e.
|
||||
running with an off_t with 32 bits.
|
||||
|
||||
Casts added where needed to still pass MSVC builds.
|
||||
|
||||
---------
|
||||
|
||||
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
|
||||
CVE: CVE-2025-5918
|
||||
|
||||
Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/89b8c35ff4b5addc08a85bf5df02b407f8af1f6c]
|
||||
|
||||
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
||||
---
|
||||
libarchive/archive_read.c | 6 ----
|
||||
libarchive/archive_read_disk_posix.c | 3 +-
|
||||
libarchive/archive_read_open_fd.c | 29 +++++++++++++------
|
||||
libarchive/archive_read_open_file.c | 35 ++++++++++++-----------
|
||||
libarchive/archive_read_open_filename.c | 37 ++++++++++++++++++-------
|
||||
libarchive/test/read_open_memory.c | 2 +-
|
||||
libarchive/test/test_sparse_basic.c | 6 ++--
|
||||
libarchive/test/test_tar_large.c | 2 +-
|
||||
8 files changed, 75 insertions(+), 45 deletions(-)
|
||||
|
||||
diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c
|
||||
index 822c534..50db870 100644
|
||||
--- a/libarchive/archive_read.c
|
||||
+++ b/libarchive/archive_read.c
|
||||
@@ -176,15 +176,9 @@ client_skip_proxy(struct archive_read_filter *self, int64_t request)
|
||||
return 0;
|
||||
|
||||
if (self->archive->client.skipper != NULL) {
|
||||
- /* Seek requests over 1GiB are broken down into
|
||||
- * multiple seeks. This avoids overflows when the
|
||||
- * requests get passed through 32-bit arguments. */
|
||||
- int64_t skip_limit = (int64_t)1 << 30;
|
||||
int64_t total = 0;
|
||||
for (;;) {
|
||||
int64_t get, ask = request;
|
||||
- if (ask > skip_limit)
|
||||
- ask = skip_limit;
|
||||
get = (self->archive->client.skipper)
|
||||
(&self->archive->archive, self->data, ask);
|
||||
total += get;
|
||||
diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c
|
||||
index 09965eb..4839d62 100644
|
||||
--- a/libarchive/archive_read_disk_posix.c
|
||||
+++ b/libarchive/archive_read_disk_posix.c
|
||||
@@ -778,7 +778,8 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
*/
|
||||
if (t->current_sparse->offset > t->entry_total) {
|
||||
if (lseek(t->entry_fd,
|
||||
- (off_t)t->current_sparse->offset, SEEK_SET) < 0) {
|
||||
+ (off_t)t->current_sparse->offset, SEEK_SET) !=
|
||||
+ t->current_sparse->offset) {
|
||||
archive_set_error(&a->archive, errno, "Seek error");
|
||||
r = ARCHIVE_FATAL;
|
||||
a->archive.state = ARCHIVE_STATE_FATAL;
|
||||
diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c
|
||||
index debfde2..3fd536d 100644
|
||||
--- a/libarchive/archive_read_open_fd.c
|
||||
+++ b/libarchive/archive_read_open_fd.c
|
||||
@@ -131,7 +131,7 @@ static int64_t
|
||||
file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
- int64_t skip = request;
|
||||
+ off_t skip = (off_t)request;
|
||||
int64_t old_offset, new_offset;
|
||||
int skip_bits = sizeof(skip) * 8 - 1; /* off_t is a signed type. */
|
||||
|
||||
@@ -140,15 +140,15 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
|
||||
/* Reduce a request that would overflow the 'skip' variable. */
|
||||
if (sizeof(request) > sizeof(skip)) {
|
||||
- int64_t max_skip =
|
||||
+ const int64_t max_skip =
|
||||
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
|
||||
if (request > max_skip)
|
||||
- skip = max_skip;
|
||||
+ skip = (off_t)max_skip;
|
||||
}
|
||||
|
||||
- /* Reduce request to the next smallest multiple of block_size */
|
||||
- request = (request / mine->block_size) * mine->block_size;
|
||||
- if (request == 0)
|
||||
+ /* Reduce 'skip' to the next smallest multiple of block_size */
|
||||
+ skip = (off_t)(((int64_t)skip / mine->block_size) * mine->block_size);
|
||||
+ if (skip == 0)
|
||||
return (0);
|
||||
|
||||
if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
|
||||
@@ -178,11 +178,24 @@ static int64_t
|
||||
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_fd_data *mine = (struct read_fd_data *)client_data;
|
||||
+ off_t seek = (off_t)request;
|
||||
int64_t r;
|
||||
+ int seek_bits = sizeof(seek) * 8 - 1; /* off_t is a signed type. */
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
- /* See above for notes about when off_t is less than 64 bits. */
|
||||
- r = lseek(mine->fd, request, whence);
|
||||
+
|
||||
+ /* Reduce a request that would overflow the 'seek' variable. */
|
||||
+ if (sizeof(request) > sizeof(seek)) {
|
||||
+ const int64_t max_seek =
|
||||
+ (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
|
||||
+ const int64_t min_seek = ~max_seek;
|
||||
+ if (request > max_seek)
|
||||
+ seek = (off_t)max_seek;
|
||||
+ else if (request < min_seek)
|
||||
+ seek = (off_t)min_seek;
|
||||
+ }
|
||||
+
|
||||
+ r = lseek(mine->fd, seek, whence);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
|
||||
index ecd56dc..2829b9a 100644
|
||||
--- a/libarchive/archive_read_open_file.c
|
||||
+++ b/libarchive/archive_read_open_file.c
|
||||
@@ -145,7 +145,7 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
|
||||
|
||||
/* If request is too big for a long or an off_t, reduce it. */
|
||||
if (sizeof(request) > sizeof(skip)) {
|
||||
- int64_t max_skip =
|
||||
+ const int64_t max_skip =
|
||||
(((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
|
||||
if (request > max_skip)
|
||||
skip = max_skip;
|
||||
@@ -176,39 +176,42 @@ FILE_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_FILE_data *mine = (struct read_FILE_data *)client_data;
|
||||
#if HAVE__FSEEKI64
|
||||
- int64_t skip = request;
|
||||
+ int64_t seek = request;
|
||||
#elif HAVE_FSEEKO
|
||||
- off_t skip = (off_t)request;
|
||||
+ off_t seek = (off_t)request;
|
||||
#else
|
||||
- long skip = (long)request;
|
||||
+ long seek = (long)request;
|
||||
#endif
|
||||
- int skip_bits = sizeof(skip) * 8 - 1;
|
||||
+ int seek_bits = sizeof(seek) * 8 - 1;
|
||||
(void)a; /* UNUSED */
|
||||
|
||||
- /* If request is too big for a long or an off_t, reduce it. */
|
||||
- if (sizeof(request) > sizeof(skip)) {
|
||||
- int64_t max_skip =
|
||||
- (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
|
||||
- if (request > max_skip)
|
||||
- skip = max_skip;
|
||||
+ /* Reduce a request that would overflow the 'seek' variable. */
|
||||
+ if (sizeof(request) > sizeof(seek)) {
|
||||
+ const int64_t max_seek =
|
||||
+ (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
|
||||
+ const int64_t min_seek = ~max_seek;
|
||||
+ if (request > max_seek)
|
||||
+ seek = max_seek;
|
||||
+ else if (request < min_seek)
|
||||
+ seek = min_seek;
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* Newer Android versions have fseeko...to meditate. */
|
||||
- int64_t ret = lseek(fileno(mine->f), skip, whence);
|
||||
+ int64_t ret = lseek(fileno(mine->f), seek, whence);
|
||||
if (ret >= 0) {
|
||||
return ret;
|
||||
}
|
||||
#elif HAVE__FSEEKI64
|
||||
- if (_fseeki64(mine->f, skip, whence) == 0) {
|
||||
+ if (_fseeki64(mine->f, seek, whence) == 0) {
|
||||
return _ftelli64(mine->f);
|
||||
}
|
||||
#elif HAVE_FSEEKO
|
||||
- if (fseeko(mine->f, skip, whence) == 0) {
|
||||
+ if (fseeko(mine->f, seek, whence) == 0) {
|
||||
return ftello(mine->f);
|
||||
}
|
||||
#else
|
||||
- if (fseek(mine->f, skip, whence) == 0) {
|
||||
+ if (fseek(mine->f, seek, whence) == 0) {
|
||||
return ftell(mine->f);
|
||||
}
|
||||
#endif
|
||||
@@ -226,4 +229,4 @@ FILE_close(struct archive *a, void *client_data)
|
||||
free(mine->buffer);
|
||||
free(mine);
|
||||
return (ARCHIVE_OK);
|
||||
-}
|
||||
\ No newline at end of file
|
||||
+}
|
||||
diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c
|
||||
index 05f0ffb..3894b15 100644
|
||||
--- a/libarchive/archive_read_open_filename.c
|
||||
+++ b/libarchive/archive_read_open_filename.c
|
||||
@@ -479,20 +479,24 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* We use _lseeki64() on Windows. */
|
||||
- int64_t old_offset, new_offset;
|
||||
+ int64_t old_offset, new_offset, skip = request;
|
||||
#else
|
||||
- off_t old_offset, new_offset;
|
||||
+ off_t old_offset, new_offset, skip = (off_t)request;
|
||||
#endif
|
||||
+ int skip_bits = sizeof(skip) * 8 - 1;
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
|
||||
- /* TODO: Deal with case where off_t isn't 64 bits.
|
||||
- * This shouldn't be a problem on Linux or other POSIX
|
||||
- * systems, since the configuration logic for libarchive
|
||||
- * tries to obtain a 64-bit off_t.
|
||||
- */
|
||||
+ /* Reduce a request that would overflow the 'skip' variable. */
|
||||
+ if (sizeof(request) > sizeof(skip)) {
|
||||
+ const int64_t max_skip =
|
||||
+ (((int64_t)1 << (skip_bits - 1)) - 1) * 2 + 1;
|
||||
+ if (request > max_skip)
|
||||
+ skip = max_skip;
|
||||
+ }
|
||||
+
|
||||
if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
|
||||
- (new_offset = lseek(mine->fd, request, SEEK_CUR)) >= 0)
|
||||
+ (new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
|
||||
return (new_offset - old_offset);
|
||||
|
||||
/* If lseek() fails, don't bother trying again. */
|
||||
@@ -540,11 +544,24 @@ static int64_t
|
||||
file_seek(struct archive *a, void *client_data, int64_t request, int whence)
|
||||
{
|
||||
struct read_file_data *mine = (struct read_file_data *)client_data;
|
||||
+ off_t seek = (off_t)request;
|
||||
int64_t r;
|
||||
+ int seek_bits = sizeof(seek) * 8 - 1;
|
||||
|
||||
/* We use off_t here because lseek() is declared that way. */
|
||||
- /* See above for notes about when off_t is less than 64 bits. */
|
||||
- r = lseek(mine->fd, request, whence);
|
||||
+
|
||||
+ /* Reduce a request that would overflow the 'seek' variable. */
|
||||
+ if (sizeof(request) > sizeof(seek)) {
|
||||
+ const int64_t max_seek =
|
||||
+ (((int64_t)1 << (seek_bits - 1)) - 1) * 2 + 1;
|
||||
+ const int64_t min_seek = ~max_seek;
|
||||
+ if (request > max_seek)
|
||||
+ seek = (off_t)max_seek;
|
||||
+ else if (request < min_seek)
|
||||
+ seek = (off_t)min_seek;
|
||||
+ }
|
||||
+
|
||||
+ r = lseek(mine->fd, seek, whence);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
||||
diff --git a/libarchive/test/read_open_memory.c b/libarchive/test/read_open_memory.c
|
||||
index 6d2468c..9262ab9 100644
|
||||
--- a/libarchive/test/read_open_memory.c
|
||||
+++ b/libarchive/test/read_open_memory.c
|
||||
@@ -167,7 +167,7 @@ memory_read_skip(struct archive *a, void *client_data, int64_t skip)
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
/* We can't skip by more than is available. */
|
||||
- if ((off_t)skip > (off_t)(mine->end - mine->p))
|
||||
+ if (skip > mine->end - mine->p)
|
||||
skip = mine->end - mine->p;
|
||||
/* Always do small skips by prime amounts. */
|
||||
if (skip > 71)
|
||||
diff --git a/libarchive/test/test_sparse_basic.c b/libarchive/test/test_sparse_basic.c
|
||||
index 23cde56..93710cb 100644
|
||||
--- a/libarchive/test/test_sparse_basic.c
|
||||
+++ b/libarchive/test/test_sparse_basic.c
|
||||
@@ -608,7 +608,8 @@ DEFINE_TEST(test_sparse_basic)
|
||||
verify_sparse_file(a, "file2", sparse_file2, 20);
|
||||
/* Encoded non sparse; expect a data block but no sparse entries. */
|
||||
verify_sparse_file(a, "file3", sparse_file3, 0);
|
||||
- verify_sparse_file(a, "file4", sparse_file4, 2);
|
||||
+ if (sizeof(off_t) > 4)
|
||||
+ verify_sparse_file(a, "file4", sparse_file4, 2);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
@@ -635,7 +636,8 @@ DEFINE_TEST(test_sparse_basic)
|
||||
verify_sparse_file(a, "file1", sparse_file1, 0);
|
||||
verify_sparse_file(a, "file2", sparse_file2, 0);
|
||||
verify_sparse_file(a, "file3", sparse_file3, 0);
|
||||
- verify_sparse_file(a, "file4", sparse_file4, 0);
|
||||
+ if (sizeof(off_t) > 4)
|
||||
+ verify_sparse_file(a, "file4", sparse_file4, 0);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
diff --git a/libarchive/test/test_tar_large.c b/libarchive/test/test_tar_large.c
|
||||
index c1f3791..1cde321 100644
|
||||
--- a/libarchive/test/test_tar_large.c
|
||||
+++ b/libarchive/test/test_tar_large.c
|
||||
@@ -175,7 +175,7 @@ memory_read_skip(struct archive *a, void *_private, int64_t skip)
|
||||
}
|
||||
if (private->filebytes > 0) {
|
||||
if (private->filebytes < skip)
|
||||
- skip = (off_t)private->filebytes;
|
||||
+ skip = private->filebytes;
|
||||
private->filebytes -= skip;
|
||||
} else {
|
||||
skip = 0;
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
From dcbf1e0ededa95849f098d154a25876ed5754bcf Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <stoeckmann@users.noreply.github.com>
|
||||
Date: Tue, 15 Apr 2025 06:02:17 +0200
|
||||
Subject: [PATCH] Do not skip past EOF while reading (#2584)
|
||||
|
||||
Make sure to not skip past end of file for better error messages. One
|
||||
such example is now visible with rar testsuite. You can see the
|
||||
difference already by an actually not useless use of cat:
|
||||
|
||||
```
|
||||
$ cat .../test_read_format_rar_ppmd_use_after_free.rar | bsdtar -t
|
||||
bsdtar: Archive entry has empty or unreadable filename ... skipping.
|
||||
bsdtar: Archive entry has empty or unreadable filename ... skipping.
|
||||
bsdtar: Truncated input file (needed 119 bytes, only 0 available)
|
||||
bsdtar: Error exit delayed from previous errors.
|
||||
```
|
||||
|
||||
compared to
|
||||
|
||||
```
|
||||
$ bsdtar -tf .../test_read_format_rar_ppmd_use_after_free.rar
|
||||
bsdtar: Archive entry has empty or unreadable filename ... skipping.
|
||||
bsdtar: Archive entry has empty or unreadable filename ... skipping.
|
||||
bsdtar: Error exit delayed from previous errors.
|
||||
```
|
||||
|
||||
Since the former cannot lseek, the error is a different one
|
||||
(ARCHIVE_FATAL vs ARCHIVE_EOF). The piped version states explicitly that
|
||||
truncation occurred, while the latter states EOF because the skip past
|
||||
the end of file was successful.
|
||||
|
||||
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
|
||||
CVE: CVE-2025-5918
|
||||
|
||||
Upstream-Status: Backport [https://github.com/libarchive/libarchive/commit/dcbf1e0ededa95849f098d154a25876ed5754bcf]
|
||||
|
||||
Signed-off-by: Divya Chellam <divya.chellam@windriver.com>
|
||||
---
|
||||
libarchive/archive_read_open_fd.c | 13 +++++++---
|
||||
libarchive/archive_read_open_file.c | 33 +++++++++++++++++++------
|
||||
libarchive/archive_read_open_filename.c | 16 +++++++++---
|
||||
libarchive/test/test_read_format_rar.c | 6 ++---
|
||||
4 files changed, 50 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/libarchive/archive_read_open_fd.c b/libarchive/archive_read_open_fd.c
|
||||
index 3fd536d..dc7c9e5 100644
|
||||
--- a/libarchive/archive_read_open_fd.c
|
||||
+++ b/libarchive/archive_read_open_fd.c
|
||||
@@ -52,6 +52,7 @@
|
||||
struct read_fd_data {
|
||||
int fd;
|
||||
size_t block_size;
|
||||
+ int64_t size;
|
||||
char use_lseek;
|
||||
void *buffer;
|
||||
};
|
||||
@@ -95,6 +96,7 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size)
|
||||
if (S_ISREG(st.st_mode)) {
|
||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||
mine->use_lseek = 1;
|
||||
+ mine->size = st.st_size;
|
||||
}
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
setmode(mine->fd, O_BINARY);
|
||||
@@ -151,9 +153,14 @@ file_skip(struct archive *a, void *client_data, int64_t request)
|
||||
if (skip == 0)
|
||||
return (0);
|
||||
|
||||
- if (((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) &&
|
||||
- ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0))
|
||||
- return (new_offset - old_offset);
|
||||
+ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) {
|
||||
+ if (old_offset >= mine->size ||
|
||||
+ skip > mine->size - old_offset) {
|
||||
+ /* Do not seek past end of file. */
|
||||
+ errno = ESPIPE;
|
||||
+ } else if ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
|
||||
+ return (new_offset - old_offset);
|
||||
+ }
|
||||
|
||||
/* If seek failed once, it will probably fail again. */
|
||||
mine->use_lseek = 0;
|
||||
diff --git a/libarchive/archive_read_open_file.c b/libarchive/archive_read_open_file.c
|
||||
index 2829b9a..6ed18a0 100644
|
||||
--- a/libarchive/archive_read_open_file.c
|
||||
+++ b/libarchive/archive_read_open_file.c
|
||||
@@ -52,6 +52,7 @@
|
||||
struct read_FILE_data {
|
||||
FILE *f;
|
||||
size_t block_size;
|
||||
+ int64_t size;
|
||||
void *buffer;
|
||||
char can_skip;
|
||||
};
|
||||
@@ -91,6 +92,7 @@ archive_read_open_FILE(struct archive *a, FILE *f)
|
||||
archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
|
||||
/* Enable the seek optimization only for regular files. */
|
||||
mine->can_skip = 1;
|
||||
+ mine->size = st.st_size;
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||
@@ -130,6 +132,7 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
|
||||
#else
|
||||
long skip = (long)request;
|
||||
#endif
|
||||
+ int64_t old_offset, new_offset;
|
||||
int skip_bits = sizeof(skip) * 8 - 1;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
@@ -153,19 +156,33 @@ FILE_skip(struct archive *a, void *client_data, int64_t request)
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/* fileno() isn't safe on all platforms ... see above. */
|
||||
- if (lseek(fileno(mine->f), skip, SEEK_CUR) < 0)
|
||||
+ old_offset = lseek(fileno(mine->f), 0, SEEK_CUR);
|
||||
#elif HAVE__FSEEKI64
|
||||
- if (_fseeki64(mine->f, skip, SEEK_CUR) != 0)
|
||||
+ old_offset = _ftelli64(mine->f);
|
||||
#elif HAVE_FSEEKO
|
||||
- if (fseeko(mine->f, skip, SEEK_CUR) != 0)
|
||||
+ old_offset = ftello(mine->f);
|
||||
#else
|
||||
- if (fseek(mine->f, skip, SEEK_CUR) != 0)
|
||||
+ old_offset = ftell(mine->f);
|
||||
#endif
|
||||
- {
|
||||
- mine->can_skip = 0;
|
||||
- return (0);
|
||||
+ if (old_offset >= 0) {
|
||||
+ if (old_offset < mine->size &&
|
||||
+ skip <= mine->size - old_offset) {
|
||||
+#ifdef __ANDROID__
|
||||
+ new_offset = lseek(fileno(mine->f), skip, SEEK_CUR);
|
||||
+#elif HAVE__FSEEKI64
|
||||
+ new_offset = _fseeki64(mine->f, skip, SEEK_CUR);
|
||||
+#elif HAVE_FSEEKO
|
||||
+ new_offset = fseeko(mine->f, skip, SEEK_CUR);
|
||||
+#else
|
||||
+ new_offset = fseek(mine->f, skip, SEEK_CUR);
|
||||
+#endif
|
||||
+ if (new_offset >= 0)
|
||||
+ return (new_offset - old_offset);
|
||||
+ }
|
||||
}
|
||||
- return (request);
|
||||
+
|
||||
+ mine->can_skip = 0;
|
||||
+ return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/libarchive/archive_read_open_filename.c b/libarchive/archive_read_open_filename.c
|
||||
index 3894b15..5f5b3f1 100644
|
||||
--- a/libarchive/archive_read_open_filename.c
|
||||
+++ b/libarchive/archive_read_open_filename.c
|
||||
@@ -74,6 +74,7 @@ struct read_file_data {
|
||||
size_t block_size;
|
||||
void *buffer;
|
||||
mode_t st_mode; /* Mode bits for opened file. */
|
||||
+ int64_t size;
|
||||
char use_lseek;
|
||||
enum fnt_e { FNT_STDIN, FNT_MBS, FNT_WCS } filename_type;
|
||||
union {
|
||||
@@ -400,8 +401,10 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->st_mode = st.st_mode;
|
||||
|
||||
/* Disk-like inputs can use lseek(). */
|
||||
- if (is_disk_like)
|
||||
+ if (is_disk_like) {
|
||||
mine->use_lseek = 1;
|
||||
+ mine->size = st.st_size;
|
||||
+ }
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
fail:
|
||||
@@ -495,9 +498,14 @@ file_skip_lseek(struct archive *a, void *client_data, int64_t request)
|
||||
skip = max_skip;
|
||||
}
|
||||
|
||||
- if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0 &&
|
||||
- (new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
|
||||
- return (new_offset - old_offset);
|
||||
+ if ((old_offset = lseek(mine->fd, 0, SEEK_CUR)) >= 0) {
|
||||
+ if (old_offset >= mine->size ||
|
||||
+ skip > mine->size - old_offset) {
|
||||
+ /* Do not seek past end of file. */
|
||||
+ errno = ESPIPE;
|
||||
+ } else if ((new_offset = lseek(mine->fd, skip, SEEK_CUR)) >= 0)
|
||||
+ return (new_offset - old_offset);
|
||||
+ }
|
||||
|
||||
/* If lseek() fails, don't bother trying again. */
|
||||
mine->use_lseek = 0;
|
||||
diff --git a/libarchive/test/test_read_format_rar.c b/libarchive/test/test_read_format_rar.c
|
||||
index dce567a..fce44a9 100644
|
||||
--- a/libarchive/test/test_read_format_rar.c
|
||||
+++ b/libarchive/test/test_read_format_rar.c
|
||||
@@ -3829,8 +3829,8 @@ DEFINE_TEST(test_read_format_rar_ppmd_use_after_free)
|
||||
assertA(ARCHIVE_OK == archive_read_next_header(a, &ae));
|
||||
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
|
||||
|
||||
- /* Test EOF */
|
||||
- assertA(1 == archive_read_next_header(a, &ae));
|
||||
+ /* Test for truncation */
|
||||
+ assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
@@ -3856,7 +3856,7 @@ DEFINE_TEST(test_read_format_rar_ppmd_use_after_free2)
|
||||
assertA(archive_read_data(a, buf, sizeof(buf)) <= 0);
|
||||
|
||||
/* Test EOF */
|
||||
- assertA(1 == archive_read_next_header(a, &ae));
|
||||
+ assertA(ARCHIVE_FATAL == archive_read_next_header(a, &ae));
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
--
|
||||
2.40.0
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
To work with autoconf 2.73, tweak the macro ordering in configure.in.
|
||||
|
||||
Upstream-Status: Pending
|
||||
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
|
||||
---
|
||||
configure.ac | 26 +++++++++++++-------------
|
||||
1 file changed, 13 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 5668d41..7e65e49 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -435,6 +435,19 @@ if test "x$with_bz2lib" != "xno"; then
|
||||
esac
|
||||
fi
|
||||
|
||||
+# Checks for typedefs, structures, and compiler characteristics.
|
||||
+AC_C_CONST
|
||||
+# la_TYPE_UID_T defaults to "int", which is incorrect for MinGW
|
||||
+# and MSVC. Use a customized version.
|
||||
+la_TYPE_UID_T
|
||||
+AC_TYPE_MODE_T
|
||||
+# AC_TYPE_OFF_T defaults to "long", which limits us to 4GB files on
|
||||
+# most systems... default to "long long" instead.
|
||||
+AC_CHECK_TYPE(off_t, [long long])
|
||||
+AC_TYPE_SIZE_T
|
||||
+AC_CHECK_TYPE(id_t, [unsigned long])
|
||||
+AC_CHECK_TYPE(uintptr_t, [unsigned int])
|
||||
+
|
||||
AC_ARG_WITH([libb2],
|
||||
AS_HELP_STRING([--without-libb2], [Don't build support for BLAKE2 through libb2]))
|
||||
|
||||
@@ -694,19 +707,6 @@ fi
|
||||
|
||||
AC_SUBST(DEAD_CODE_REMOVAL)
|
||||
|
||||
-# Checks for typedefs, structures, and compiler characteristics.
|
||||
-AC_C_CONST
|
||||
-# la_TYPE_UID_T defaults to "int", which is incorrect for MinGW
|
||||
-# and MSVC. Use a customized version.
|
||||
-la_TYPE_UID_T
|
||||
-AC_TYPE_MODE_T
|
||||
-# AC_TYPE_OFF_T defaults to "long", which limits us to 4GB files on
|
||||
-# most systems... default to "long long" instead.
|
||||
-AC_CHECK_TYPE(off_t, [long long])
|
||||
-AC_TYPE_SIZE_T
|
||||
-AC_CHECK_TYPE(id_t, [unsigned long])
|
||||
-AC_CHECK_TYPE(uintptr_t, [unsigned int])
|
||||
-
|
||||
# Check for tm_gmtoff in struct tm
|
||||
AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,
|
||||
[
|
||||
--
|
||||
2.40.0
|
||||
@@ -0,0 +1,72 @@
|
||||
SUMMARY = "Support for reading various archive formats"
|
||||
DESCRIPTION = "C library and command-line tools for reading and writing tar, cpio, zip, ISO, and other archive formats"
|
||||
HOMEPAGE = "http://www.libarchive.org/"
|
||||
SECTION = "devel"
|
||||
LICENSE = "BSD-2-Clause"
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=d499814247adaee08d88080841cb5665"
|
||||
|
||||
DEPENDS = "e2fsprogs-native"
|
||||
|
||||
PACKAGECONFIG ?= "zlib bz2 xz zstd ${@bb.utils.filter('DISTRO_FEATURES', 'acl xattr', d)}"
|
||||
|
||||
DEPENDS_BZIP2 = "bzip2-replacement-native"
|
||||
DEPENDS_BZIP2:class-target = "bzip2"
|
||||
|
||||
PACKAGECONFIG[acl] = "--enable-acl,--disable-acl,acl,"
|
||||
PACKAGECONFIG[xattr] = "--enable-xattr,--disable-xattr,attr,"
|
||||
PACKAGECONFIG[zlib] = "--with-zlib,--without-zlib,zlib,"
|
||||
PACKAGECONFIG[bz2] = "--with-bz2lib,--without-bz2lib,${DEPENDS_BZIP2},"
|
||||
PACKAGECONFIG[xz] = "--with-lzma,--without-lzma,xz,"
|
||||
PACKAGECONFIG[openssl] = "--with-openssl,--without-openssl,openssl,"
|
||||
PACKAGECONFIG[libb2] = "--with-libb2,--without-libb2,libb2,"
|
||||
PACKAGECONFIG[libxml2] = "--with-xml2,--without-xml2,libxml2,"
|
||||
PACKAGECONFIG[expat] = "--with-expat,--without-expat,expat,"
|
||||
PACKAGECONFIG[lzo] = "--with-lzo2,--without-lzo2,lzo,"
|
||||
PACKAGECONFIG[nettle] = "--with-nettle,--without-nettle,nettle,"
|
||||
PACKAGECONFIG[lz4] = "--with-lz4,--without-lz4,lz4,"
|
||||
PACKAGECONFIG[mbedtls] = "--with-mbedtls,--without-mbedtls,mbedtls,"
|
||||
PACKAGECONFIG[zstd] = "--with-zstd,--without-zstd,zstd,"
|
||||
|
||||
EXTRA_OECONF += "--enable-largefile --without-iconv"
|
||||
|
||||
SRC_URI = "http://libarchive.org/downloads/libarchive-${PV}.tar.gz \
|
||||
file://configurehack.patch \
|
||||
file://CVE-2025-5914.patch \
|
||||
file://CVE-2025-5915.patch \
|
||||
file://CVE-2025-5916.patch \
|
||||
file://CVE-2025-5917.patch \
|
||||
file://CVE-2025-5918-0001.patch \
|
||||
file://CVE-2025-5918-0002.patch \
|
||||
"
|
||||
UPSTREAM_CHECK_URI = "http://libarchive.org/"
|
||||
|
||||
SRC_URI[sha256sum] = "aa90732c5a6bdda52fda2ad468ac98d75be981c15dde263d7b5cf6af66fd009f"
|
||||
|
||||
inherit autotools update-alternatives pkgconfig
|
||||
|
||||
CPPFLAGS += "-I${WORKDIR}/extra-includes"
|
||||
|
||||
do_configure[cleandirs] += "${WORKDIR}/extra-includes"
|
||||
do_configure:prepend() {
|
||||
# We just need the headers for some type constants, so no need to
|
||||
# build all of e2fsprogs for the target
|
||||
cp -R ${STAGING_INCDIR_NATIVE}/ext2fs ${WORKDIR}/extra-includes/
|
||||
}
|
||||
|
||||
ALTERNATIVE_PRIORITY = "80"
|
||||
|
||||
PACKAGES =+ "bsdtar"
|
||||
FILES:bsdtar = "${bindir}/bsdtar"
|
||||
|
||||
ALTERNATIVE:bsdtar = "tar"
|
||||
ALTERNATIVE_LINK_NAME[tar] = "${base_bindir}/tar"
|
||||
ALTERNATIVE_TARGET[tar] = "${bindir}/bsdtar"
|
||||
|
||||
PACKAGES =+ "bsdcpio"
|
||||
FILES:bsdcpio = "${bindir}/bsdcpio"
|
||||
|
||||
ALTERNATIVE:bsdcpio = "cpio"
|
||||
ALTERNATIVE_LINK_NAME[cpio] = "${base_bindir}/cpio"
|
||||
ALTERNATIVE_TARGET[cpio] = "${bindir}/bsdcpio"
|
||||
|
||||
BBCLASSEXTEND = "native nativesdk"
|
||||
Reference in New Issue
Block a user