import RHEL 10 Beta libarchive-3.7.2-7.el10
This commit is contained in:
parent
10cb27b9b8
commit
29ecd93d70
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
SOURCES/libarchive-3.3.3.tar.gz
|
libarchive-3.7.2.tar.gz
|
||||||
|
@ -1 +0,0 @@
|
|||||||
499a8f48a895faff4151d7398b24070d578f0b2e SOURCES/libarchive-3.3.3.tar.gz
|
|
24
0001-Drop-rmd160-from-OpenSSL.patch
Normal file
24
0001-Drop-rmd160-from-OpenSSL.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From 375bbe7d20284f205ebb73652ef61ae6fceac344 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lukas Javorsky <ljavorsk@redhat.com>
|
||||||
|
Date: Tue, 18 Jul 2023 10:29:22 +0000
|
||||||
|
Subject: [PATCH] Drop rmd160 from OpenSSL
|
||||||
|
|
||||||
|
---
|
||||||
|
configure.ac | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/configure.ac b/configure.ac
|
||||||
|
index 7f5dbdf..179fb2d 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -1300,7 +1300,6 @@ if test "x$with_openssl" != "xno"; then
|
||||||
|
LIBSREQUIRED="$LIBSREQUIRED${LIBSREQUIRED:+ }libcrypto"
|
||||||
|
AC_CHECK_LIB(crypto,OPENSSL_config)
|
||||||
|
CRYPTO_CHECK(MD5, OPENSSL, md5)
|
||||||
|
- CRYPTO_CHECK(RMD160, OPENSSL, rmd160)
|
||||||
|
CRYPTO_CHECK(SHA1, OPENSSL, sha1)
|
||||||
|
CRYPTO_CHECK(SHA256, OPENSSL, sha256)
|
||||||
|
CRYPTO_CHECK(SHA384, OPENSSL, sha384)
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,32 @@
|
|||||||
|
From 3bd918d92f8c34ba12de9c6604d96f9e262a59fc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Martin Matuska <martin@matuska.de>
|
||||||
|
Date: Tue, 12 Sep 2023 08:54:47 +0200
|
||||||
|
Subject: [PATCH] tests: fix zstd long option test for 32-bit architectures
|
||||||
|
|
||||||
|
Fixes #1968
|
||||||
|
---
|
||||||
|
libarchive/test/test_write_filter_zstd.c | 8 ++++++--
|
||||||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libarchive/test/test_write_filter_zstd.c b/libarchive/test/test_write_filter_zstd.c
|
||||||
|
index 3cdbd812..c9731f1b 100644
|
||||||
|
--- a/libarchive/test/test_write_filter_zstd.c
|
||||||
|
+++ b/libarchive/test/test_write_filter_zstd.c
|
||||||
|
@@ -161,8 +161,12 @@ DEFINE_TEST(test_write_filter_zstd)
|
||||||
|
archive_write_set_filter_option(a, NULL, "max-frame-size", "1048576"));
|
||||||
|
#endif
|
||||||
|
#if ZSTD_VERSION_NUMBER >= MINVER_LONG
|
||||||
|
- assertEqualIntA(a, ARCHIVE_OK,
|
||||||
|
- archive_write_set_filter_option(a, NULL, "long", "27"));
|
||||||
|
+ if ((int)(sizeof(size_t) == 4))
|
||||||
|
+ assertEqualIntA(a, ARCHIVE_OK,
|
||||||
|
+ archive_write_set_filter_option(a, NULL, "long", "26"));
|
||||||
|
+ else
|
||||||
|
+ assertEqualIntA(a, ARCHIVE_OK,
|
||||||
|
+ archive_write_set_filter_option(a, NULL, "long", "27"));
|
||||||
|
assertEqualIntA(a, ARCHIVE_FAILED,
|
||||||
|
archive_write_set_filter_option(a, NULL, "long", "-1")); /* negative */
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
25
0003-fix-OOB-in-rar-e8-filter.patch
Normal file
25
0003-fix-OOB-in-rar-e8-filter.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From 2910a5736c3f238d2cde6cc757b01868d877ebcb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wei-Cheng Pan <legnaleurc@gmail.com>
|
||||||
|
Date: Sun, 21 Apr 2024 19:11:42 +0900
|
||||||
|
Subject: [PATCH] fix: OOB in rar e8 filter
|
||||||
|
|
||||||
|
---
|
||||||
|
libarchive/archive_read_support_format_rar.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
||||||
|
index 99a11d17..266d0ee9 100644
|
||||||
|
--- a/libarchive/archive_read_support_format_rar.c
|
||||||
|
+++ b/libarchive/archive_read_support_format_rar.c
|
||||||
|
@@ -3615,7 +3615,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
|
||||||
|
uint32_t filesize = 0x1000000;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
- if (length > PROGRAM_WORK_SIZE || length < 4)
|
||||||
|
+ if (length > PROGRAM_WORK_SIZE || length <= 4)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i <= length - 5; i++)
|
||||||
|
--
|
||||||
|
2.45.1
|
||||||
|
|
119
0004-rar4-reader-protect-copy_from_lzss_window_to_unp-217.patch
Normal file
119
0004-rar4-reader-protect-copy_from_lzss_window_to_unp-217.patch
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
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.
|
||||||
|
|
||||||
|
Security: CVE-2024-20696
|
||||||
|
---
|
||||||
|
libarchive/archive_read_support_format_rar.c | 28 +++++++++++++-------
|
||||||
|
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
||||||
|
index 4fc6626c..5776df4b 100644
|
||||||
|
--- a/libarchive/archive_read_support_format_rar.c
|
||||||
|
+++ b/libarchive/archive_read_support_format_rar.c
|
||||||
|
@@ -432,7 +432,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
|
||||||
|
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);
|
||||||
|
@@ -2060,7 +2060,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||||
|
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;
|
||||||
|
@@ -2213,7 +2213,7 @@ read_data_compressed(struct archive_read *a, const void **buff, size_t *size,
|
||||||
|
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;
|
||||||
|
@@ -3094,11 +3094,16 @@ copy_from_lzss_window(struct archive_read *a, void *buffer,
|
||||||
|
|
||||||
|
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)
|
||||||
|
@@ -3110,17 +3115,17 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
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],
|
||||||
|
@@ -3130,9 +3135,7 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
|
||||||
|
&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)
|
||||||
|
@@ -3140,6 +3143,11 @@ copy_from_lzss_window_to_unp(struct archive_read *a, const void **buffer,
|
||||||
|
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 *
|
||||||
|
--
|
||||||
|
2.45.1
|
||||||
|
|
@ -1,146 +0,0 @@
|
|||||||
From 9d178fe573818764a2d15e0a39691f5eb4e300f6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Mon, 27 May 2019 10:52:51 +0200
|
|
||||||
Subject: [PATCH] Fix a few obvious resource leaks and strcpy() misuses
|
|
||||||
|
|
||||||
Per Coverity report.
|
|
||||||
---
|
|
||||||
cpio/cpio.c | 4 +++-
|
|
||||||
libarchive/archive_acl.c | 8 ++++++--
|
|
||||||
libarchive/archive_write_set_format_iso9660.c | 4 ++--
|
|
||||||
libarchive/archive_write_set_format_mtree.c | 4 ++--
|
|
||||||
libarchive/archive_write_set_format_pax.c | 6 ++++--
|
|
||||||
libarchive/archive_write_set_format_xar.c | 10 ++++++----
|
|
||||||
6 files changed, 23 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/cpio/cpio.c b/cpio/cpio.c
|
|
||||||
index 5beedd0..6696bb5 100644
|
|
||||||
--- a/cpio/cpio.c
|
|
||||||
+++ b/cpio/cpio.c
|
|
||||||
@@ -744,8 +744,10 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
|
||||||
}
|
|
||||||
if (cpio->option_rename)
|
|
||||||
destpath = cpio_rename(destpath);
|
|
||||||
- if (destpath == NULL)
|
|
||||||
+ if (destpath == NULL) {
|
|
||||||
+ archive_entry_free(entry);
|
|
||||||
return (0);
|
|
||||||
+ }
|
|
||||||
archive_entry_copy_pathname(entry, destpath);
|
|
||||||
|
|
||||||
/*
|
|
||||||
diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c
|
|
||||||
index b8b6b63..503f379 100644
|
|
||||||
--- a/libarchive/archive_acl.c
|
|
||||||
+++ b/libarchive/archive_acl.c
|
|
||||||
@@ -753,8 +753,10 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
|
|
||||||
append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
|
|
||||||
wname, ap->permset, id);
|
|
||||||
count++;
|
|
||||||
- } else if (r < 0 && errno == ENOMEM)
|
|
||||||
+ } else if (r < 0 && errno == ENOMEM) {
|
|
||||||
+ free(ws);
|
|
||||||
return (NULL);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add terminating character */
|
|
||||||
@@ -975,8 +977,10 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
|
||||||
prefix = NULL;
|
|
||||||
r = archive_mstring_get_mbs_l(
|
|
||||||
&ap->name, &name, &len, sc);
|
|
||||||
- if (r != 0)
|
|
||||||
+ if (r != 0) {
|
|
||||||
+ free(s);
|
|
||||||
return (NULL);
|
|
||||||
+ }
|
|
||||||
if (count > 0)
|
|
||||||
*p++ = separator;
|
|
||||||
if (name == NULL ||
|
|
||||||
diff --git a/libarchive/archive_write_set_format_iso9660.c b/libarchive/archive_write_set_format_iso9660.c
|
|
||||||
index c0ca435..badc88b 100644
|
|
||||||
--- a/libarchive/archive_write_set_format_iso9660.c
|
|
||||||
+++ b/libarchive/archive_write_set_format_iso9660.c
|
|
||||||
@@ -4899,10 +4899,10 @@ isofile_gen_utility_names(struct archive_write *a, struct isofile *file)
|
|
||||||
if (p[0] == '/') {
|
|
||||||
if (p[1] == '/')
|
|
||||||
/* Convert '//' --> '/' */
|
|
||||||
- strcpy(p, p+1);
|
|
||||||
+ memmove(p, p+1, strlen(p+1) + 1);
|
|
||||||
else if (p[1] == '.' && p[2] == '/')
|
|
||||||
/* Convert '/./' --> '/' */
|
|
||||||
- strcpy(p, p+2);
|
|
||||||
+ memmove(p, p+2, strlen(p+2) + 1);
|
|
||||||
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
|
|
||||||
/* Convert 'dir/dir1/../dir2/'
|
|
||||||
* --> 'dir/dir2/'
|
|
||||||
diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
|
|
||||||
index 493d473..0f2431e 100644
|
|
||||||
--- a/libarchive/archive_write_set_format_mtree.c
|
|
||||||
+++ b/libarchive/archive_write_set_format_mtree.c
|
|
||||||
@@ -1810,10 +1810,10 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
|
|
||||||
if (p[0] == '/') {
|
|
||||||
if (p[1] == '/')
|
|
||||||
/* Convert '//' --> '/' */
|
|
||||||
- strcpy(p, p+1);
|
|
||||||
+ memmove(p, p+1, strlen(p+1) + 1);
|
|
||||||
else if (p[1] == '.' && p[2] == '/')
|
|
||||||
/* Convert '/./' --> '/' */
|
|
||||||
- strcpy(p, p+2);
|
|
||||||
+ memmove(p, p+2, strlen(p+2) + 1);
|
|
||||||
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
|
|
||||||
/* Convert 'dir/dir1/../dir2/'
|
|
||||||
* --> 'dir/dir2/'
|
|
||||||
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
|
|
||||||
index 0eaf733..4863e46 100644
|
|
||||||
--- a/libarchive/archive_write_set_format_pax.c
|
|
||||||
+++ b/libarchive/archive_write_set_format_pax.c
|
|
||||||
@@ -522,11 +522,13 @@ add_pax_acl(struct archive_write *a,
|
|
||||||
ARCHIVE_ERRNO_FILE_FORMAT, "%s %s %s",
|
|
||||||
"Can't translate ", attr, " to UTF-8");
|
|
||||||
return(ARCHIVE_WARN);
|
|
||||||
- } else if (*p != '\0') {
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (*p != '\0') {
|
|
||||||
add_pax_attr(&(pax->pax_header),
|
|
||||||
attr, p);
|
|
||||||
- free(p);
|
|
||||||
}
|
|
||||||
+ free(p);
|
|
||||||
return(ARCHIVE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_set_format_xar.c b/libarchive/archive_write_set_format_xar.c
|
|
||||||
index 495f0d4..56cd33c 100644
|
|
||||||
--- a/libarchive/archive_write_set_format_xar.c
|
|
||||||
+++ b/libarchive/archive_write_set_format_xar.c
|
|
||||||
@@ -2120,10 +2120,10 @@ file_gen_utility_names(struct archive_write *a, struct file *file)
|
|
||||||
if (p[0] == '/') {
|
|
||||||
if (p[1] == '/')
|
|
||||||
/* Convert '//' --> '/' */
|
|
||||||
- strcpy(p, p+1);
|
|
||||||
+ memmove(p, p+1, strlen(p+1) + 1);
|
|
||||||
else if (p[1] == '.' && p[2] == '/')
|
|
||||||
/* Convert '/./' --> '/' */
|
|
||||||
- strcpy(p, p+2);
|
|
||||||
+ memmove(p, p+2, strlen(p+2) + 1);
|
|
||||||
else if (p[1] == '.' && p[2] == '.' && p[3] == '/') {
|
|
||||||
/* Convert 'dir/dir1/../dir2/'
|
|
||||||
* --> 'dir/dir2/'
|
|
||||||
@@ -3169,8 +3169,10 @@ save_xattrs(struct archive_write *a, struct file *file)
|
|
||||||
checksum_update(&(xar->a_sumwrk),
|
|
||||||
xar->wbuff, size);
|
|
||||||
if (write_to_temp(a, xar->wbuff, size)
|
|
||||||
- != ARCHIVE_OK)
|
|
||||||
- return (ARCHIVE_FATAL);
|
|
||||||
+ != ARCHIVE_OK) {
|
|
||||||
+ free(heap);
|
|
||||||
+ return (ARCHIVE_FATAL);
|
|
||||||
+ }
|
|
||||||
if (r == ARCHIVE_OK) {
|
|
||||||
xar->stream.next_out = xar->wbuff;
|
|
||||||
xar->stream.avail_out = sizeof(xar->wbuff);
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
|||||||
From 6a71cce7ed735f83f9a6a6bad8beaa47f8d14734 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Mon, 27 May 2019 10:06:14 +0200
|
|
||||||
Subject: [PATCH 1/2] Fix use-after-free in delayed link processing (newc
|
|
||||||
format)
|
|
||||||
|
|
||||||
During archiving, if some of the "delayed" hard link entries
|
|
||||||
happened to disappear on filesystem (or become unreadable) for
|
|
||||||
some reason (most probably race), the old code free()d the 'entry'
|
|
||||||
and continued with the loop; the next loop though dereferenced
|
|
||||||
'entry' and crashed the archiver.
|
|
||||||
|
|
||||||
Per report from Coverity.
|
|
||||||
---
|
|
||||||
tar/write.c | 9 ++++-----
|
|
||||||
1 file changed, 4 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tar/write.c b/tar/write.c
|
|
||||||
index 9c24566..3970de2 100644
|
|
||||||
--- a/tar/write.c
|
|
||||||
+++ b/tar/write.c
|
|
||||||
@@ -540,8 +540,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
|
|
||||||
lafe_warnc(archive_errno(disk),
|
|
||||||
"%s", archive_error_string(disk));
|
|
||||||
bsdtar->return_value = 1;
|
|
||||||
- archive_entry_free(entry);
|
|
||||||
- continue;
|
|
||||||
+ goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -559,13 +558,13 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
|
|
||||||
bsdtar->return_value = 1;
|
|
||||||
else
|
|
||||||
archive_read_close(disk);
|
|
||||||
- archive_entry_free(entry);
|
|
||||||
- continue;
|
|
||||||
+ goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_file(bsdtar, a, entry);
|
|
||||||
- archive_entry_free(entry);
|
|
||||||
archive_read_close(disk);
|
|
||||||
+next_entry:
|
|
||||||
+ archive_entry_free(entry);
|
|
||||||
entry = NULL;
|
|
||||||
archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
||||||
|
|
||||||
From a999ca882aeb8fce4f4f2ee1317f528984b47e8e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Mon, 27 May 2019 10:34:48 +0200
|
|
||||||
Subject: [PATCH 2/2] call missing archive_read_close() in write_archive()
|
|
||||||
|
|
||||||
---
|
|
||||||
tar/write.c | 3 +--
|
|
||||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tar/write.c b/tar/write.c
|
|
||||||
index 3970de2..63c619c 100644
|
|
||||||
--- a/tar/write.c
|
|
||||||
+++ b/tar/write.c
|
|
||||||
@@ -556,8 +556,7 @@ write_archive(struct archive *a, struct bsdtar *bsdtar)
|
|
||||||
"%s", archive_error_string(disk));
|
|
||||||
if (r == ARCHIVE_FATAL)
|
|
||||||
bsdtar->return_value = 1;
|
|
||||||
- else
|
|
||||||
- archive_read_close(disk);
|
|
||||||
+ archive_read_close(disk);
|
|
||||||
goto next_entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
|||||||
From 65a23f5dbee4497064e9bb467f81138a62b0dae1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Axtens <dja@axtens.net>
|
|
||||||
Date: Tue, 1 Jan 2019 16:01:40 +1100
|
|
||||||
Subject: [PATCH 2/2] 7zip: fix crash when parsing certain archives
|
|
||||||
|
|
||||||
Fuzzing with CRCs disabled revealed that a call to get_uncompressed_data()
|
|
||||||
would sometimes fail to return at least 'minimum' bytes. This can cause
|
|
||||||
the crc32() invocation in header_bytes to read off into invalid memory.
|
|
||||||
|
|
||||||
A specially crafted archive can use this to cause a crash.
|
|
||||||
|
|
||||||
An ASAN trace is below, but ASAN is not required - an uninstrumented
|
|
||||||
binary will also crash.
|
|
||||||
|
|
||||||
==7719==ERROR: AddressSanitizer: SEGV on unknown address 0x631000040000 (pc 0x7fbdb3b3ec1d bp 0x7ffe77a51310 sp 0x7ffe77a51150 T0)
|
|
||||||
==7719==The signal is caused by a READ memory access.
|
|
||||||
#0 0x7fbdb3b3ec1c in crc32_z (/lib/x86_64-linux-gnu/libz.so.1+0x2c1c)
|
|
||||||
#1 0x84f5eb in header_bytes (/tmp/libarchive/bsdtar+0x84f5eb)
|
|
||||||
#2 0x856156 in read_Header (/tmp/libarchive/bsdtar+0x856156)
|
|
||||||
#3 0x84e134 in slurp_central_directory (/tmp/libarchive/bsdtar+0x84e134)
|
|
||||||
#4 0x849690 in archive_read_format_7zip_read_header (/tmp/libarchive/bsdtar+0x849690)
|
|
||||||
#5 0x5713b7 in _archive_read_next_header2 (/tmp/libarchive/bsdtar+0x5713b7)
|
|
||||||
#6 0x570e63 in _archive_read_next_header (/tmp/libarchive/bsdtar+0x570e63)
|
|
||||||
#7 0x6f08bd in archive_read_next_header (/tmp/libarchive/bsdtar+0x6f08bd)
|
|
||||||
#8 0x52373f in read_archive (/tmp/libarchive/bsdtar+0x52373f)
|
|
||||||
#9 0x5257be in tar_mode_x (/tmp/libarchive/bsdtar+0x5257be)
|
|
||||||
#10 0x51daeb in main (/tmp/libarchive/bsdtar+0x51daeb)
|
|
||||||
#11 0x7fbdb27cab96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
|
|
||||||
#12 0x41dd09 in _start (/tmp/libarchive/bsdtar+0x41dd09)
|
|
||||||
|
|
||||||
This was primarly done with afl and FairFuzz. Some early corpus entries
|
|
||||||
may have been generated by qsym.
|
|
||||||
---
|
|
||||||
libarchive/archive_read_support_format_7zip.c | 8 +-------
|
|
||||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_read_support_format_7zip.c b/libarchive/archive_read_support_format_7zip.c
|
|
||||||
index bccbf896..b6d1505d 100644
|
|
||||||
--- a/libarchive/archive_read_support_format_7zip.c
|
|
||||||
+++ b/libarchive/archive_read_support_format_7zip.c
|
|
||||||
@@ -2964,13 +2964,7 @@ get_uncompressed_data(struct archive_read *a, const void **buff, size_t size,
|
|
||||||
if (zip->codec == _7Z_COPY && zip->codec2 == (unsigned long)-1) {
|
|
||||||
/* Copy mode. */
|
|
||||||
|
|
||||||
- /*
|
|
||||||
- * Note: '1' here is a performance optimization.
|
|
||||||
- * Recall that the decompression layer returns a count of
|
|
||||||
- * available bytes; asking for more than that forces the
|
|
||||||
- * decompressor to combine reads by copying data.
|
|
||||||
- */
|
|
||||||
- *buff = __archive_read_ahead(a, 1, &bytes_avail);
|
|
||||||
+ *buff = __archive_read_ahead(a, minimum, &bytes_avail);
|
|
||||||
if (bytes_avail <= 0) {
|
|
||||||
archive_set_error(&a->archive,
|
|
||||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
|||||||
From 8312eaa576014cd9b965012af51bc1f967b12423 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Axtens <dja@axtens.net>
|
|
||||||
Date: Tue, 1 Jan 2019 17:10:49 +1100
|
|
||||||
Subject: [PATCH 1/2] iso9660: Fail when expected Rockridge extensions is
|
|
||||||
missing
|
|
||||||
|
|
||||||
A corrupted or malicious ISO9660 image can cause read_CE() to loop
|
|
||||||
forever.
|
|
||||||
|
|
||||||
read_CE() calls parse_rockridge(), expecting a Rockridge extension
|
|
||||||
to be read. However, parse_rockridge() is structured as a while
|
|
||||||
loop starting with a sanity check, and if the sanity check fails
|
|
||||||
before the loop has run, the function returns ARCHIVE_OK without
|
|
||||||
advancing the position in the file. This causes read_CE() to retry
|
|
||||||
indefinitely.
|
|
||||||
|
|
||||||
Make parse_rockridge() return ARCHIVE_WARN if it didn't read an
|
|
||||||
extension. As someone with no real knowledge of the format, this
|
|
||||||
seems more apt than ARCHIVE_FATAL, but both the call-sites escalate
|
|
||||||
it to a fatal error immediately anyway.
|
|
||||||
|
|
||||||
Found with a combination of AFL, afl-rb (FairFuzz) and qsym.
|
|
||||||
---
|
|
||||||
libarchive/archive_read_support_format_iso9660.c | 11 ++++++++++-
|
|
||||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_read_support_format_iso9660.c b/libarchive/archive_read_support_format_iso9660.c
|
|
||||||
index 28acfefb..bad8f1df 100644
|
|
||||||
--- a/libarchive/archive_read_support_format_iso9660.c
|
|
||||||
+++ b/libarchive/archive_read_support_format_iso9660.c
|
|
||||||
@@ -2102,6 +2102,7 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
|
||||||
const unsigned char *p, const unsigned char *end)
|
|
||||||
{
|
|
||||||
struct iso9660 *iso9660;
|
|
||||||
+ int entry_seen = 0;
|
|
||||||
|
|
||||||
iso9660 = (struct iso9660 *)(a->format->data);
|
|
||||||
|
|
||||||
@@ -2257,8 +2258,16 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
|
|
||||||
}
|
|
||||||
|
|
||||||
p += p[2];
|
|
||||||
+ entry_seen = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (entry_seen)
|
|
||||||
+ return (ARCHIVE_OK);
|
|
||||||
+ else {
|
|
||||||
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
||||||
+ "Tried to parse Rockridge extensions, but none found");
|
|
||||||
+ return (ARCHIVE_WARN);
|
|
||||||
}
|
|
||||||
- return (ARCHIVE_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
--
|
|
||||||
2.20.1
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
From 88311f46cdfc719d26bb99d3b47944eb92ceae02 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Tue, 30 Apr 2019 11:50:33 +0200
|
|
||||||
Subject: [PATCH] Avoid a double-free when a window size of 0 is specified
|
|
||||||
|
|
||||||
new_size can be 0 with a malicious or corrupted RAR archive.
|
|
||||||
|
|
||||||
realloc(area, 0) is equivalent to free(area), so the region would
|
|
||||||
be free()d here and the free()d again in the cleanup function.
|
|
||||||
|
|
||||||
Found with a setup running AFL, afl-rb, and qsym.
|
|
||||||
---
|
|
||||||
libarchive/archive_read_support_format_rar.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
|
||||||
index c4a8278..3f88eef 100644
|
|
||||||
--- a/libarchive/archive_read_support_format_rar.c
|
|
||||||
+++ b/libarchive/archive_read_support_format_rar.c
|
|
||||||
@@ -2317,6 +2317,11 @@ parse_codes(struct archive_read *a)
|
|
||||||
new_size = DICTIONARY_MAX_SIZE;
|
|
||||||
else
|
|
||||||
new_size = rar_fls((unsigned int)rar->unp_size) << 1;
|
|
||||||
+ if (new_size == 0) {
|
|
||||||
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
||||||
+ "Zero window size is invalid.");
|
|
||||||
+ return (ARCHIVE_FATAL);
|
|
||||||
+ }
|
|
||||||
new_window = realloc(rar->lzss.window, new_size);
|
|
||||||
if (new_window == NULL) {
|
|
||||||
archive_set_error(&a->archive, ENOMEM,
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
|||||||
From d00ccaf8c20efbd009964e3e2697d26907d14163 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Tue, 30 Apr 2019 11:36:08 +0200
|
|
||||||
Subject: [PATCH] rar: file split across multi-part archives must match
|
|
||||||
|
|
||||||
Fuzzing uncovered some UAF and memory overrun bugs where a file in a
|
|
||||||
single file archive reported that it was split across multiple
|
|
||||||
volumes. This was caused by ppmd7 operations calling
|
|
||||||
rar_br_fillup. This would invoke rar_read_ahead, which would in some
|
|
||||||
situations invoke archive_read_format_rar_read_header. That would
|
|
||||||
check the new file name against the old file name, and if they didn't
|
|
||||||
match up it would free the ppmd7 buffer and allocate a new
|
|
||||||
one. However, because the ppmd7 decoder wasn't actually done with the
|
|
||||||
buffer, it would continue to used the freed buffer. Both reads and
|
|
||||||
writes to the freed region can be observed.
|
|
||||||
|
|
||||||
This is quite tricky to solve: once the buffer has been freed it is
|
|
||||||
too late, as the ppmd7 decoder functions almost universally assume
|
|
||||||
success - there's no way for ppmd_read to signal error, nor are there
|
|
||||||
good ways for functions like Range_Normalise to propagate them. So we
|
|
||||||
can't detect after the fact that we're in an invalid state - e.g. by
|
|
||||||
checking rar->cursor, we have to prevent ourselves from ever ending up
|
|
||||||
there. So, when we are in the dangerous part or rar_read_ahead that
|
|
||||||
assumes a valid split, we set a flag force read_header to either go
|
|
||||||
down the path for split files or bail. This means that the ppmd7
|
|
||||||
decoder keeps a valid buffer and just runs out of data.
|
|
||||||
|
|
||||||
Found with a combination of AFL, afl-rb and qsym.
|
|
||||||
---
|
|
||||||
libarchive/archive_read_support_format_rar.c | 9 +++++++++
|
|
||||||
1 file changed, 9 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
|
||||||
index cbb14c3..c4a8278 100644
|
|
||||||
--- a/libarchive/archive_read_support_format_rar.c
|
|
||||||
+++ b/libarchive/archive_read_support_format_rar.c
|
|
||||||
@@ -258,6 +258,7 @@ struct rar
|
|
||||||
struct data_block_offsets *dbo;
|
|
||||||
unsigned int cursor;
|
|
||||||
unsigned int nodes;
|
|
||||||
+ char filename_must_match;
|
|
||||||
|
|
||||||
/* LZSS members */
|
|
||||||
struct huffman_code maincode;
|
|
||||||
@@ -1570,6 +1571,12 @@ read_header(struct archive_read *a, struct archive_entry *entry,
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+ else if (rar->filename_must_match)
|
|
||||||
+ {
|
|
||||||
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
|
||||||
+ "Mismatch of file parts split across multi-volume archive");
|
|
||||||
+ return (ARCHIVE_FATAL);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
rar->filename_save = (char*)realloc(rar->filename_save,
|
|
||||||
filename_size + 1);
|
|
||||||
@@ -2938,12 +2945,14 @@ rar_read_ahead(struct archive_read *a, size_t min, ssize_t *avail)
|
|
||||||
else if (*avail == 0 && rar->main_flags & MHD_VOLUME &&
|
|
||||||
rar->file_flags & FHD_SPLIT_AFTER)
|
|
||||||
{
|
|
||||||
+ rar->filename_must_match = 1;
|
|
||||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
|
||||||
if (ret == (ARCHIVE_EOF))
|
|
||||||
{
|
|
||||||
rar->has_endarc_header = 1;
|
|
||||||
ret = archive_read_format_rar_read_header(a, a->entry);
|
|
||||||
}
|
|
||||||
+ rar->filename_must_match = 0;
|
|
||||||
if (ret != (ARCHIVE_OK))
|
|
||||||
return NULL;
|
|
||||||
return rar_read_ahead(a, min, avail);
|
|
||||||
--
|
|
||||||
2.17.1
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
|||||||
From 1abcbf1af5209631ccf4fca4ddcab3c863294c85 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Patrik=20Novotn=C3=BD?= <panovotn@redhat.com>
|
|
||||||
Date: Wed, 15 Jan 2020 16:10:04 +0100
|
|
||||||
Subject: [PATCH] RAR reader: fix use after free
|
|
||||||
|
|
||||||
If read_data_compressed() returns ARCHIVE_FAILED, the caller is allowed
|
|
||||||
to continue with next archive headers. We need to set rar->start_new_table
|
|
||||||
after the ppmd7_context got freed, otherwise it won't be allocated again.
|
|
||||||
---
|
|
||||||
libarchive/archive_read_support_format_rar.c | 4 +++-
|
|
||||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_read_support_format_rar.c b/libarchive/archive_read_support_format_rar.c
|
|
||||||
index cbb14c32..9c26ef97 100644
|
|
||||||
--- a/libarchive/archive_read_support_format_rar.c
|
|
||||||
+++ b/libarchive/archive_read_support_format_rar.c
|
|
||||||
@@ -1037,8 +1037,10 @@ archive_read_format_rar_read_data(struct archive_read *a, const void **buff,
|
|
||||||
case COMPRESS_METHOD_GOOD:
|
|
||||||
case COMPRESS_METHOD_BEST:
|
|
||||||
ret = read_data_compressed(a, buff, size, offset);
|
|
||||||
- if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN)
|
|
||||||
+ if (ret != ARCHIVE_OK && ret != ARCHIVE_WARN) {
|
|
||||||
__archive_ppmd7_functions.Ppmd7_Free(&rar->ppmd7_context);
|
|
||||||
+ rar->start_new_table = 1;
|
|
||||||
+ }
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
--
|
|
||||||
2.24.1
|
|
||||||
|
|
@ -1,98 +0,0 @@
|
|||||||
From 72085b30bf30867360c4aa77bd43de5e1788d875 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Tue, 24 Mar 2020 09:22:47 +0100
|
|
||||||
Subject: [PATCH] Bugfix and optimize archive_wstring_append_from_mbs()
|
|
||||||
|
|
||||||
The cal to mbrtowc() or mbtowc() should read up to mbs_length
|
|
||||||
bytes and not wcs_length. This avoids out-of-bounds reads.
|
|
||||||
|
|
||||||
mbrtowc() and mbtowc() return (size_t)-1 wit errno EILSEQ when
|
|
||||||
they encounter an invalid multibyte character and (size_t)-2 when
|
|
||||||
they they encounter an incomplete multibyte character. As we return
|
|
||||||
failure and all our callers error out it makes no sense to continue
|
|
||||||
parsing mbs.
|
|
||||||
|
|
||||||
As we allocate `len` wchars at the beginning and each wchar has
|
|
||||||
at least one byte, there will never be need to grow the buffer,
|
|
||||||
so the code can be left out. On the other hand, we are always
|
|
||||||
allocatng more memory than we need.
|
|
||||||
|
|
||||||
As long as wcs_length == mbs_length == len we can omit wcs_length.
|
|
||||||
We keep the old code commented if we decide to save memory and
|
|
||||||
use autoexpanding wcs_length in the future.
|
|
||||||
---
|
|
||||||
libarchive/archive_string.c | 28 +++++++++++++++++-----------
|
|
||||||
1 file changed, 17 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
|
|
||||||
index 5ae09b6..d7541dc 100644
|
|
||||||
--- a/libarchive/archive_string.c
|
|
||||||
+++ b/libarchive/archive_string.c
|
|
||||||
@@ -590,7 +590,7 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
|
||||||
* No single byte will be more than one wide character,
|
|
||||||
* so this length estimate will always be big enough.
|
|
||||||
*/
|
|
||||||
- size_t wcs_length = len;
|
|
||||||
+ //size_t wcs_length = len;
|
|
||||||
size_t mbs_length = len;
|
|
||||||
const char *mbs = p;
|
|
||||||
wchar_t *wcs;
|
|
||||||
@@ -599,7 +599,11 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
|
||||||
|
|
||||||
memset(&shift_state, 0, sizeof(shift_state));
|
|
||||||
#endif
|
|
||||||
- if (NULL == archive_wstring_ensure(dest, dest->length + wcs_length + 1))
|
|
||||||
+ /*
|
|
||||||
+ * As we decided to have wcs_length == mbs_length == len
|
|
||||||
+ * we can use len here instead of wcs_length
|
|
||||||
+ */
|
|
||||||
+ if (NULL == archive_wstring_ensure(dest, dest->length + len + 1))
|
|
||||||
return (-1);
|
|
||||||
wcs = dest->s + dest->length;
|
|
||||||
/*
|
|
||||||
@@ -608,6 +612,12 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
|
||||||
* multi bytes.
|
|
||||||
*/
|
|
||||||
while (*mbs && mbs_length > 0) {
|
|
||||||
+ /*
|
|
||||||
+ * The buffer we allocated is always big enough.
|
|
||||||
+ * Keep this code path in a comment if we decide to choose
|
|
||||||
+ * smaller wcs_length in the future
|
|
||||||
+ */
|
|
||||||
+/*
|
|
||||||
if (wcs_length == 0) {
|
|
||||||
dest->length = wcs - dest->s;
|
|
||||||
dest->s[dest->length] = L'\0';
|
|
||||||
@@ -617,24 +627,20 @@ archive_wstring_append_from_mbs(struct archive_wstring *dest,
|
|
||||||
return (-1);
|
|
||||||
wcs = dest->s + dest->length;
|
|
||||||
}
|
|
||||||
+*/
|
|
||||||
#if HAVE_MBRTOWC
|
|
||||||
- r = mbrtowc(wcs, mbs, wcs_length, &shift_state);
|
|
||||||
+ r = mbrtowc(wcs, mbs, mbs_length, &shift_state);
|
|
||||||
#else
|
|
||||||
- r = mbtowc(wcs, mbs, wcs_length);
|
|
||||||
+ r = mbtowc(wcs, mbs, mbs_length);
|
|
||||||
#endif
|
|
||||||
if (r == (size_t)-1 || r == (size_t)-2) {
|
|
||||||
ret_val = -1;
|
|
||||||
- if (errno == EILSEQ) {
|
|
||||||
- ++mbs;
|
|
||||||
- --mbs_length;
|
|
||||||
- continue;
|
|
||||||
- } else
|
|
||||||
- break;
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
if (r == 0 || r > mbs_length)
|
|
||||||
break;
|
|
||||||
wcs++;
|
|
||||||
- wcs_length--;
|
|
||||||
+ //wcs_length--;
|
|
||||||
mbs += r;
|
|
||||||
mbs_length -= r;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.24.1
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
|||||||
From fba4f123cc456d2b2538f811bb831483bf336bad Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Sat, 21 Aug 2021 20:51:07 +0200
|
|
||||||
Subject: [PATCH 1/2] Fix handling of symbolic link ACLs
|
|
||||||
|
|
||||||
On Linux ACLs on symbolic links are not supported.
|
|
||||||
We must avoid calling acl_set_file() on symbolic links as their
|
|
||||||
targets are modified instead.
|
|
||||||
|
|
||||||
While here, do not try to set default ACLs on non-directories.
|
|
||||||
|
|
||||||
Fixes #1565
|
|
||||||
---
|
|
||||||
libarchive/archive_disk_acl_freebsd.c | 20 +++++++++++++++-----
|
|
||||||
libarchive/archive_disk_acl_linux.c | 23 ++++++++++++++++++++---
|
|
||||||
libarchive/archive_disk_acl_sunos.c | 13 +++++++++----
|
|
||||||
3 files changed, 44 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_disk_acl_freebsd.c b/libarchive/archive_disk_acl_freebsd.c
|
|
||||||
index aba41e5d..ed4e7a78 100644
|
|
||||||
--- a/libarchive/archive_disk_acl_freebsd.c
|
|
||||||
+++ b/libarchive/archive_disk_acl_freebsd.c
|
|
||||||
@@ -319,7 +319,7 @@ translate_acl(struct archive_read_disk *a,
|
|
||||||
|
|
||||||
static int
|
|
||||||
set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
- struct archive_acl *abstract_acl,
|
|
||||||
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
|
|
||||||
int ae_requested_type, const char *tname)
|
|
||||||
{
|
|
||||||
int acl_type = 0;
|
|
||||||
@@ -364,6 +364,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
return (ARCHIVE_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) {
|
|
||||||
+ errno = EINVAL;
|
|
||||||
+ archive_set_error(a, errno,
|
|
||||||
+ "Cannot set default ACL on non-directory");
|
|
||||||
+ return (ARCHIVE_WARN);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
acl = acl_init(entries);
|
|
||||||
if (acl == (acl_t)NULL) {
|
|
||||||
archive_set_error(a, errno,
|
|
||||||
@@ -542,7 +549,10 @@ set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
else if (acl_set_link_np(name, acl_type, acl) != 0)
|
|
||||||
#else
|
|
||||||
/* FreeBSD older than 8.0 */
|
|
||||||
- else if (acl_set_file(name, acl_type, acl) != 0)
|
|
||||||
+ else if (S_ISLNK(mode)) {
|
|
||||||
+ /* acl_set_file() follows symbolic links, skip */
|
|
||||||
+ ret = ARCHIVE_OK;
|
|
||||||
+ } else if (acl_set_file(name, acl_type, acl) != 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (errno == EOPNOTSUPP) {
|
|
||||||
@@ -677,14 +687,14 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
|
||||||
if ((archive_acl_types(abstract_acl)
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
|
||||||
if (ret != ARCHIVE_OK)
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
if ((archive_acl_types(abstract_acl)
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
|
||||||
|
|
||||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
|
||||||
@@ -693,7 +703,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
|
||||||
#if ARCHIVE_ACL_FREEBSD_NFS4
|
|
||||||
else if ((archive_acl_types(abstract_acl) &
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
diff --git a/libarchive/archive_disk_acl_linux.c b/libarchive/archive_disk_acl_linux.c
|
|
||||||
index 3928f3d6..31d27053 100644
|
|
||||||
--- a/libarchive/archive_disk_acl_linux.c
|
|
||||||
+++ b/libarchive/archive_disk_acl_linux.c
|
|
||||||
@@ -343,6 +343,11 @@ set_richacl(struct archive *a, int fd, const char *name,
|
|
||||||
return (ARCHIVE_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (S_ISLNK(mode)) {
|
|
||||||
+ /* Linux does not support RichACLs on symbolic links */
|
|
||||||
+ return (ARCHIVE_OK);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
richacl = richacl_alloc(entries);
|
|
||||||
if (richacl == NULL) {
|
|
||||||
archive_set_error(a, errno,
|
|
||||||
@@ -455,7 +460,7 @@ exit_free:
|
|
||||||
#if ARCHIVE_ACL_LIBACL
|
|
||||||
static int
|
|
||||||
set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
- struct archive_acl *abstract_acl,
|
|
||||||
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
|
|
||||||
int ae_requested_type, const char *tname)
|
|
||||||
{
|
|
||||||
int acl_type = 0;
|
|
||||||
@@ -488,6 +493,18 @@ set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
return (ARCHIVE_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (S_ISLNK(mode)) {
|
|
||||||
+ /* Linux does not support ACLs on symbolic links */
|
|
||||||
+ return (ARCHIVE_OK);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (acl_type == ACL_TYPE_DEFAULT && !S_ISDIR(mode)) {
|
|
||||||
+ errno = EINVAL;
|
|
||||||
+ archive_set_error(a, errno,
|
|
||||||
+ "Cannot set default ACL on non-directory");
|
|
||||||
+ return (ARCHIVE_WARN);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
acl = acl_init(entries);
|
|
||||||
if (acl == (acl_t)NULL) {
|
|
||||||
archive_set_error(a, errno,
|
|
||||||
@@ -727,14 +744,14 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
|
||||||
if ((archive_acl_types(abstract_acl)
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
|
||||||
if (ret != ARCHIVE_OK)
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
if ((archive_acl_types(abstract_acl)
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
|
||||||
}
|
|
||||||
#endif /* ARCHIVE_ACL_LIBACL */
|
|
||||||
diff --git a/libarchive/archive_disk_acl_sunos.c b/libarchive/archive_disk_acl_sunos.c
|
|
||||||
index b0f5dfad..0ef3ad52 100644
|
|
||||||
--- a/libarchive/archive_disk_acl_sunos.c
|
|
||||||
+++ b/libarchive/archive_disk_acl_sunos.c
|
|
||||||
@@ -443,7 +443,7 @@ translate_acl(struct archive_read_disk *a,
|
|
||||||
|
|
||||||
static int
|
|
||||||
set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
- struct archive_acl *abstract_acl,
|
|
||||||
+ struct archive_acl *abstract_acl, __LA_MODE_T mode,
|
|
||||||
int ae_requested_type, const char *tname)
|
|
||||||
{
|
|
||||||
aclent_t *aclent;
|
|
||||||
@@ -467,7 +467,6 @@ set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
if (entries == 0)
|
|
||||||
return (ARCHIVE_OK);
|
|
||||||
|
|
||||||
-
|
|
||||||
switch (ae_requested_type) {
|
|
||||||
case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
|
|
||||||
cmd = SETACL;
|
|
||||||
@@ -492,6 +491,12 @@ set_acl(struct archive *a, int fd, const char *name,
|
|
||||||
return (ARCHIVE_FAILED);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (S_ISLNK(mode)) {
|
|
||||||
+ /* Skip ACLs on symbolic links */
|
|
||||||
+ ret = ARCHIVE_OK;
|
|
||||||
+ goto exit_free;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
e = 0;
|
|
||||||
|
|
||||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
|
||||||
@@ -801,7 +806,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
|
||||||
if ((archive_acl_types(abstract_acl)
|
|
||||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
|
||||||
/* Solaris writes POSIX.1e access and default ACLs together */
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
|
|
||||||
|
|
||||||
/* Simultaneous POSIX.1e and NFSv4 is not supported */
|
|
||||||
@@ -810,7 +815,7 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
|
||||||
#if ARCHIVE_ACL_SUNOS_NFS4
|
|
||||||
else if ((archive_acl_types(abstract_acl) &
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
|
||||||
- ret = set_acl(a, fd, name, abstract_acl,
|
|
||||||
+ ret = set_acl(a, fd, name, abstract_acl, mode,
|
|
||||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,811 +0,0 @@
|
|||||||
From b837c72c423b744a2e6c554742877173406dbfa0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Sat, 25 May 2019 23:46:59 +0200
|
|
||||||
Subject: [PATCH] archive_write_disk_posix: open a fd when processing fixup
|
|
||||||
entries
|
|
||||||
|
|
||||||
---
|
|
||||||
libarchive/archive_write_disk_posix.c | 25 ++++++++++++++++++++-----
|
|
||||||
1 file changed, 20 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
|
|
||||||
index 70b27b50..0583fbd1 100644
|
|
||||||
--- a/libarchive/archive_write_disk_posix.c
|
|
||||||
+++ b/libarchive/archive_write_disk_posix.c
|
|
||||||
@@ -182,6 +182,7 @@ struct fixup_entry {
|
|
||||||
void *mac_metadata;
|
|
||||||
int fixup; /* bitmask of what needs fixing */
|
|
||||||
char *name;
|
|
||||||
+ int fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -2354,20 +2355,31 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
|
|
||||||
while (p != NULL) {
|
|
||||||
a->pst = NULL; /* Mark stat cache as out-of-date. */
|
|
||||||
+ if (p->fd < 0 && p->fixup &
|
|
||||||
+ (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {
|
|
||||||
+ p->fd = open(p->name,
|
|
||||||
+ O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);
|
|
||||||
+ }
|
|
||||||
if (p->fixup & TODO_TIMES) {
|
|
||||||
- set_times(a, -1, p->mode, p->name,
|
|
||||||
+ set_times(a, p->fd, p->mode, p->name,
|
|
||||||
p->atime, p->atime_nanos,
|
|
||||||
p->birthtime, p->birthtime_nanos,
|
|
||||||
p->mtime, p->mtime_nanos,
|
|
||||||
p->ctime, p->ctime_nanos);
|
|
||||||
}
|
|
||||||
- if (p->fixup & TODO_MODE_BASE)
|
|
||||||
+ if (p->fixup & TODO_MODE_BASE) {
|
|
||||||
+#ifdef HAVE_FCHMOD
|
|
||||||
+ if (p->fd >= 0)
|
|
||||||
+ fchmod(p->fd, p->mode);
|
|
||||||
+ else
|
|
||||||
+#endif
|
|
||||||
chmod(p->name, p->mode);
|
|
||||||
+ }
|
|
||||||
if (p->fixup & TODO_ACLS)
|
|
||||||
- archive_write_disk_set_acls(&a->archive, -1, p->name,
|
|
||||||
- &p->acl, p->mode);
|
|
||||||
+ archive_write_disk_set_acls(&a->archive, p->fd,
|
|
||||||
+ p->name, &p->acl, p->mode);
|
|
||||||
if (p->fixup & TODO_FFLAGS)
|
|
||||||
- set_fflags_platform(a, -1, p->name,
|
|
||||||
+ set_fflags_platform(a, p->fd, p->name,
|
|
||||||
p->mode, p->fflags_set, 0);
|
|
||||||
if (p->fixup & TODO_MAC_METADATA)
|
|
||||||
set_mac_metadata(a, p->name, p->mac_metadata,
|
|
||||||
@@ -2376,6 +2388,8 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
archive_acl_clear(&p->acl);
|
|
||||||
free(p->mac_metadata);
|
|
||||||
free(p->name);
|
|
||||||
+ if (p->fd >= 0)
|
|
||||||
+ close(p->fd);
|
|
||||||
free(p);
|
|
||||||
p = next;
|
|
||||||
}
|
|
||||||
@@ -2510,6 +2524,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
|
|
||||||
a->fixup_list = fe;
|
|
||||||
fe->fixup = 0;
|
|
||||||
fe->name = strdup(pathname);
|
|
||||||
+ fe->fd = -1;
|
|
||||||
return (fe);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
From 6d5204058ed51e11588a438737e9033305cfd248 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Thu, 6 Jun 2019 15:12:11 +0200
|
|
||||||
Subject: [PATCH] archive_write_disk_posix changes - private file descriptor in
|
|
||||||
_archive_write_disk_close() - use la_opendirat() in edit_deep_directories()
|
|
||||||
|
|
||||||
---
|
|
||||||
libarchive/archive_write_disk_posix.c | 25 ++++++++++++-------------
|
|
||||||
1 file changed, 12 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
|
|
||||||
index 89941c64..b1a0bb38 100644
|
|
||||||
--- a/libarchive/archive_write_disk_posix.c
|
|
||||||
+++ b/libarchive/archive_write_disk_posix.c
|
|
||||||
@@ -186,7 +186,6 @@ struct fixup_entry {
|
|
||||||
void *mac_metadata;
|
|
||||||
int fixup; /* bitmask of what needs fixing */
|
|
||||||
char *name;
|
|
||||||
- int fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -1947,7 +1946,7 @@ edit_deep_directories(struct archive_write_disk *a)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Try to record our starting dir. */
|
|
||||||
- a->restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC);
|
|
||||||
+ a->restore_pwd = open(".", O_RDONLY | O_BINARY | O_CLOEXEC | O_DIRECTORY);
|
|
||||||
__archive_ensure_cloexec_flag(a->restore_pwd);
|
|
||||||
if (a->restore_pwd < 0)
|
|
||||||
return;
|
|
||||||
@@ -2380,7 +2379,7 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
{
|
|
||||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
|
||||||
struct fixup_entry *next, *p;
|
|
||||||
- int ret;
|
|
||||||
+ int fd, ret;
|
|
||||||
|
|
||||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
|
||||||
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
|
|
||||||
@@ -2391,14 +2390,15 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
p = sort_dir_list(a->fixup_list);
|
|
||||||
|
|
||||||
while (p != NULL) {
|
|
||||||
+ fd = -1;
|
|
||||||
a->pst = NULL; /* Mark stat cache as out-of-date. */
|
|
||||||
- if (p->fd < 0 && p->fixup &
|
|
||||||
+ if (p->fixup &
|
|
||||||
(TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {
|
|
||||||
- p->fd = open(p->name,
|
|
||||||
+ fd = open(p->name,
|
|
||||||
O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_TIMES) {
|
|
||||||
- set_times(a, p->fd, p->mode, p->name,
|
|
||||||
+ set_times(a, fd, p->mode, p->name,
|
|
||||||
p->atime, p->atime_nanos,
|
|
||||||
p->birthtime, p->birthtime_nanos,
|
|
||||||
p->mtime, p->mtime_nanos,
|
|
||||||
@@ -2406,17 +2406,17 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_MODE_BASE) {
|
|
||||||
#ifdef HAVE_FCHMOD
|
|
||||||
- if (p->fd >= 0)
|
|
||||||
- fchmod(p->fd, p->mode);
|
|
||||||
+ if (fd >= 0)
|
|
||||||
+ fchmod(fd, p->mode);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
chmod(p->name, p->mode);
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_ACLS)
|
|
||||||
- archive_write_disk_set_acls(&a->archive, p->fd,
|
|
||||||
+ archive_write_disk_set_acls(&a->archive, fd,
|
|
||||||
p->name, &p->acl, p->mode);
|
|
||||||
if (p->fixup & TODO_FFLAGS)
|
|
||||||
- set_fflags_platform(a, p->fd, p->name,
|
|
||||||
+ set_fflags_platform(a, fd, p->name,
|
|
||||||
p->mode, p->fflags_set, 0);
|
|
||||||
if (p->fixup & TODO_MAC_METADATA)
|
|
||||||
set_mac_metadata(a, p->name, p->mac_metadata,
|
|
||||||
@@ -2425,8 +2425,8 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
archive_acl_clear(&p->acl);
|
|
||||||
free(p->mac_metadata);
|
|
||||||
free(p->name);
|
|
||||||
- if (p->fd >= 0)
|
|
||||||
- close(p->fd);
|
|
||||||
+ if (fd >= 0)
|
|
||||||
+ close(fd);
|
|
||||||
free(p);
|
|
||||||
p = next;
|
|
||||||
}
|
|
||||||
@@ -2561,7 +2561,6 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
|
|
||||||
a->fixup_list = fe;
|
|
||||||
fe->fixup = 0;
|
|
||||||
fe->name = strdup(pathname);
|
|
||||||
- fe->fd = -1;
|
|
||||||
return (fe);
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
From e2ad1a2c3064fa9eba6274b3641c4c1beed25c0b Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Sun, 22 Aug 2021 03:53:28 +0200
|
|
||||||
Subject: [PATCH] Never follow symlinks when setting file flags on Linux
|
|
||||||
|
|
||||||
When opening a file descriptor to set file flags on linux, ensure
|
|
||||||
no symbolic links are followed. This fixes the case when an archive
|
|
||||||
contains a directory entry followed by a symlink entry with the same
|
|
||||||
path. The fixup code would modify file flags of the symlink target.
|
|
||||||
---
|
|
||||||
libarchive/archive_write_disk_posix.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
|
|
||||||
index ba4e65df..8474617e 100644
|
|
||||||
--- a/libarchive/archive_write_disk_posix.c
|
|
||||||
+++ b/libarchive/archive_write_disk_posix.c
|
|
||||||
@@ -3927,7 +3927,8 @@ set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
|
|
||||||
|
|
||||||
/* If we weren't given an fd, open it ourselves. */
|
|
||||||
if (myfd < 0) {
|
|
||||||
- myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY | O_CLOEXEC);
|
|
||||||
+ myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY |
|
|
||||||
+ O_CLOEXEC | O_NOFOLLOW);
|
|
||||||
__archive_ensure_cloexec_flag(myfd);
|
|
||||||
}
|
|
||||||
if (myfd < 0)
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
From b41daecb5ccb4c8e3b2c53fd6147109fc12c3043 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Fri, 20 Aug 2021 01:50:27 +0200
|
|
||||||
Subject: [PATCH] Do not follow symlinks when processing the fixup list
|
|
||||||
|
|
||||||
Use lchmod() instead of chmod() and tell the remaining functions that the
|
|
||||||
real file to be modified is a symbolic link.
|
|
||||||
|
|
||||||
Fixes #1566
|
|
||||||
---
|
|
||||||
Makefile.am | 1 +
|
|
||||||
libarchive/archive_write_disk_posix.c | 24 +++++++-
|
|
||||||
libarchive/test/CMakeLists.txt | 1 +
|
|
||||||
libarchive/test/test_write_disk_fixup.c | 77 +++++++++++++++++++++++++
|
|
||||||
4 files changed, 102 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 libarchive/test/test_write_disk_fixup.c
|
|
||||||
|
|
||||||
diff --git a/Makefile.am b/Makefile.am
|
|
||||||
index 58edb74e..c93a82e9 100644
|
|
||||||
--- a/Makefile.am
|
|
||||||
+++ b/Makefile.am
|
|
||||||
@@ -560,6 +560,7 @@ libarchive_test_SOURCES= \
|
|
||||||
libarchive/test/test_write_disk.c \
|
|
||||||
libarchive/test/test_write_disk_appledouble.c \
|
|
||||||
libarchive/test/test_write_disk_failures.c \
|
|
||||||
+ libarchive/test/test_write_disk_fixup.c \
|
|
||||||
libarchive/test/test_write_disk_hardlink.c \
|
|
||||||
libarchive/test/test_write_disk_hfs_compression.c \
|
|
||||||
libarchive/test/test_write_disk_lookup.c \
|
|
||||||
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
|
|
||||||
index 8474617e..fcd733af 100644
|
|
||||||
--- a/libarchive/archive_write_disk_posix.c
|
|
||||||
+++ b/libarchive/archive_write_disk_posix.c
|
|
||||||
@@ -2461,6 +2461,7 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
{
|
|
||||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
|
||||||
struct fixup_entry *next, *p;
|
|
||||||
+ struct stat st;
|
|
||||||
int fd, ret;
|
|
||||||
|
|
||||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
|
||||||
@@ -2478,6 +2479,20 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
(TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {
|
|
||||||
fd = open(p->name,
|
|
||||||
O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);
|
|
||||||
+ if (fd == -1) {
|
|
||||||
+ /* If we cannot lstat, skip entry */
|
|
||||||
+ if (lstat(p->name, &st) != 0)
|
|
||||||
+ goto skip_fixup_entry;
|
|
||||||
+ /*
|
|
||||||
+ * If we deal with a symbolic link, mark
|
|
||||||
+ * it in the fixup mode to ensure no
|
|
||||||
+ * modifications are made to its target.
|
|
||||||
+ */
|
|
||||||
+ if (S_ISLNK(st.st_mode)) {
|
|
||||||
+ p->mode &= ~S_IFMT;
|
|
||||||
+ p->mode |= S_IFLNK;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_TIMES) {
|
|
||||||
set_times(a, fd, p->mode, p->name,
|
|
||||||
@@ -2492,7 +2507,12 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
fchmod(fd, p->mode);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
- chmod(p->name, p->mode);
|
|
||||||
+#ifdef HAVE_LCHMOD
|
|
||||||
+ lchmod(p->name, p->mode);
|
|
||||||
+#else
|
|
||||||
+ if (!S_ISLNK(p->mode))
|
|
||||||
+ chmod(p->name, p->mode);
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_ACLS)
|
|
||||||
archive_write_disk_set_acls(&a->archive, fd,
|
|
||||||
@@ -2503,6 +2523,7 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
if (p->fixup & TODO_MAC_METADATA)
|
|
||||||
set_mac_metadata(a, p->name, p->mac_metadata,
|
|
||||||
p->mac_metadata_size);
|
|
||||||
+skip_fixup_entry:
|
|
||||||
next = p->next;
|
|
||||||
archive_acl_clear(&p->acl);
|
|
||||||
free(p->mac_metadata);
|
|
||||||
@@ -2643,6 +2664,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
|
|
||||||
fe->next = a->fixup_list;
|
|
||||||
a->fixup_list = fe;
|
|
||||||
fe->fixup = 0;
|
|
||||||
+ fe->mode = 0;
|
|
||||||
fe->name = strdup(pathname);
|
|
||||||
return (fe);
|
|
||||||
}
|
|
||||||
diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt
|
|
||||||
index b26f679c..53cc3e22 100644
|
|
||||||
--- a/libarchive/test/CMakeLists.txt
|
|
||||||
+++ b/libarchive/test/CMakeLists.txt
|
|
||||||
@@ -209,6 +209,7 @@ IF(ENABLE_TEST)
|
|
||||||
test_write_disk.c
|
|
||||||
test_write_disk_appledouble.c
|
|
||||||
test_write_disk_failures.c
|
|
||||||
+ test_write_disk_fixup.c
|
|
||||||
test_write_disk_hardlink.c
|
|
||||||
test_write_disk_hfs_compression.c
|
|
||||||
test_write_disk_lookup.c
|
|
||||||
diff --git a/libarchive/test/test_write_disk_fixup.c b/libarchive/test/test_write_disk_fixup.c
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000..153cc3a9
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/libarchive/test/test_write_disk_fixup.c
|
|
||||||
@@ -0,0 +1,77 @@
|
|
||||||
+/*-
|
|
||||||
+ * Copyright (c) 2021 Martin Matuska
|
|
||||||
+ * 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"
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Test fixup entries don't follow symlinks
|
|
||||||
+ */
|
|
||||||
+DEFINE_TEST(test_write_disk_fixup)
|
|
||||||
+{
|
|
||||||
+ struct archive *ad;
|
|
||||||
+ struct archive_entry *ae;
|
|
||||||
+ int r;
|
|
||||||
+
|
|
||||||
+ if (!canSymlink()) {
|
|
||||||
+ skipping("Symlinks not supported");
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* Write entries to disk. */
|
|
||||||
+ assert((ad = archive_write_disk_new()) != NULL);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Create a file
|
|
||||||
+ */
|
|
||||||
+ assertMakeFile("victim", 0600, "a");
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Create a directory and a symlink with the same name
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+ /* Directory: dir */
|
|
||||||
+ assert((ae = archive_entry_new()) != NULL);
|
|
||||||
+ archive_entry_copy_pathname(ae, "dir");
|
|
||||||
+ archive_entry_set_mode(ae, AE_IFDIR | 0606);
|
|
||||||
+ assertEqualIntA(ad, 0, archive_write_header(ad, ae));
|
|
||||||
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
|
||||||
+ archive_entry_free(ae);
|
|
||||||
+
|
|
||||||
+ /* Symbolic Link: dir -> foo */
|
|
||||||
+ assert((ae = archive_entry_new()) != NULL);
|
|
||||||
+ archive_entry_copy_pathname(ae, "dir");
|
|
||||||
+ archive_entry_set_mode(ae, AE_IFLNK | 0777);
|
|
||||||
+ archive_entry_set_size(ae, 0);
|
|
||||||
+ archive_entry_copy_symlink(ae, "victim");
|
|
||||||
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
|
||||||
+ if (r >= ARCHIVE_WARN)
|
|
||||||
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
|
||||||
+ archive_entry_free(ae);
|
|
||||||
+
|
|
||||||
+ assertEqualInt(ARCHIVE_OK, archive_write_free(ad));
|
|
||||||
+
|
|
||||||
+ /* Test the entries on disk. */
|
|
||||||
+ assertIsSymlink("dir", "victim");
|
|
||||||
+ assertFileMode("victim", 0600);
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
From 8a1bd5c18e896f0411a991240ce0d772bb02c840 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Fri, 27 Aug 2021 10:56:28 +0200
|
|
||||||
Subject: [PATCH] Fix following symlinks when processing the fixup list
|
|
||||||
|
|
||||||
The previous fix in b41daecb5 was incomplete. Fixup entries are
|
|
||||||
given the original path without calling cleanup_pathname().
|
|
||||||
To make sure we don't follow a symlink, we must strip trailing
|
|
||||||
slashes from the path.
|
|
||||||
|
|
||||||
The fixup entries are always directories. Make sure we try to modify
|
|
||||||
only directories by providing O_DIRECTORY to open() (if supported)
|
|
||||||
and if it fails to check directory via lstat().
|
|
||||||
|
|
||||||
Fixes #1566
|
|
||||||
---
|
|
||||||
libarchive/archive_write_disk_posix.c | 62 +++++++++++++++++--------
|
|
||||||
libarchive/test/test_write_disk_fixup.c | 44 ++++++++++++++----
|
|
||||||
2 files changed, 78 insertions(+), 28 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
|
|
||||||
index fcd733af..aadc5871 100644
|
|
||||||
--- a/libarchive/archive_write_disk_posix.c
|
|
||||||
+++ b/libarchive/archive_write_disk_posix.c
|
|
||||||
@@ -2462,6 +2462,7 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
struct archive_write_disk *a = (struct archive_write_disk *)_a;
|
|
||||||
struct fixup_entry *next, *p;
|
|
||||||
struct stat st;
|
|
||||||
+ char *c;
|
|
||||||
int fd, ret;
|
|
||||||
|
|
||||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
|
||||||
@@ -2475,24 +2476,49 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
while (p != NULL) {
|
|
||||||
fd = -1;
|
|
||||||
a->pst = NULL; /* Mark stat cache as out-of-date. */
|
|
||||||
- if (p->fixup &
|
|
||||||
- (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {
|
|
||||||
- fd = open(p->name,
|
|
||||||
- O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);
|
|
||||||
+
|
|
||||||
+ /* We must strip trailing slashes from the path to avoid
|
|
||||||
+ dereferencing symbolic links to directories */
|
|
||||||
+ c = p->name;
|
|
||||||
+ while (*c != '\0')
|
|
||||||
+ c++;
|
|
||||||
+ while (c != p->name && *(c - 1) == '/') {
|
|
||||||
+ c--;
|
|
||||||
+ *c = '\0';
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (p->fixup == 0)
|
|
||||||
+ goto skip_fixup_entry;
|
|
||||||
+ else {
|
|
||||||
+ fd = open(p->name, O_BINARY | O_NOFOLLOW | O_RDONLY
|
|
||||||
+#if defined(O_DIRECTORY)
|
|
||||||
+ | O_DIRECTORY
|
|
||||||
+#endif
|
|
||||||
+ | O_CLOEXEC);
|
|
||||||
+ /*
|
|
||||||
+ ` * If we don't support O_DIRECTORY,
|
|
||||||
+ * or open() has failed, we must stat()
|
|
||||||
+ * to verify that we are opening a directory
|
|
||||||
+ */
|
|
||||||
+#if defined(O_DIRECTORY)
|
|
||||||
if (fd == -1) {
|
|
||||||
- /* If we cannot lstat, skip entry */
|
|
||||||
- if (lstat(p->name, &st) != 0)
|
|
||||||
+ if (lstat(p->name, &st) != 0 ||
|
|
||||||
+ !S_ISDIR(st.st_mode)) {
|
|
||||||
goto skip_fixup_entry;
|
|
||||||
- /*
|
|
||||||
- * If we deal with a symbolic link, mark
|
|
||||||
- * it in the fixup mode to ensure no
|
|
||||||
- * modifications are made to its target.
|
|
||||||
- */
|
|
||||||
- if (S_ISLNK(st.st_mode)) {
|
|
||||||
- p->mode &= ~S_IFMT;
|
|
||||||
- p->mode |= S_IFLNK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+#else
|
|
||||||
+#if HAVE_FSTAT
|
|
||||||
+ if (fd > 0 && (
|
|
||||||
+ fstat(fd, &st) != 0 || !S_ISDIR(st.st_mode))) {
|
|
||||||
+ goto skip_fixup_entry;
|
|
||||||
+ } else
|
|
||||||
+#endif
|
|
||||||
+ if (lstat(p->name, &st) != 0 ||
|
|
||||||
+ !S_ISDIR(st.st_mode)) {
|
|
||||||
+ goto skip_fixup_entry;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_TIMES) {
|
|
||||||
set_times(a, fd, p->mode, p->name,
|
|
||||||
@@ -2504,14 +2530,13 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
if (p->fixup & TODO_MODE_BASE) {
|
|
||||||
#ifdef HAVE_FCHMOD
|
|
||||||
if (fd >= 0)
|
|
||||||
- fchmod(fd, p->mode);
|
|
||||||
+ fchmod(fd, p->mode & 07777);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LCHMOD
|
|
||||||
- lchmod(p->name, p->mode);
|
|
||||||
+ lchmod(p->name, p->mode & 07777);
|
|
||||||
#else
|
|
||||||
- if (!S_ISLNK(p->mode))
|
|
||||||
- chmod(p->name, p->mode);
|
|
||||||
+ chmod(p->name, p->mode & 07777);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (p->fixup & TODO_ACLS)
|
|
||||||
@@ -2664,7 +2689,6 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
|
|
||||||
fe->next = a->fixup_list;
|
|
||||||
a->fixup_list = fe;
|
|
||||||
fe->fixup = 0;
|
|
||||||
- fe->mode = 0;
|
|
||||||
fe->name = strdup(pathname);
|
|
||||||
return (fe);
|
|
||||||
}
|
|
||||||
diff --git a/libarchive/test/test_write_disk_fixup.c b/libarchive/test/test_write_disk_fixup.c
|
|
||||||
index c399c984..b83b7307 100644
|
|
||||||
--- a/libarchive/test/test_write_disk_fixup.c
|
|
||||||
+++ b/libarchive/test/test_write_disk_fixup.c
|
|
||||||
@@ -47,26 +47,50 @@ DEFINE_TEST(test_write_disk_fixup)
|
|
||||||
/*
|
|
||||||
* Create a file
|
|
||||||
*/
|
|
||||||
- assertMakeFile("victim", 0600, "a");
|
|
||||||
+ assertMakeFile("file", 0600, "a");
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Create a directory
|
|
||||||
+ */
|
|
||||||
+ assertMakeDir("dir", 0700);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a directory and a symlink with the same name
|
|
||||||
*/
|
|
||||||
|
|
||||||
- /* Directory: dir */
|
|
||||||
+ /* Directory: dir1 */
|
|
||||||
+ assert((ae = archive_entry_new()) != NULL);
|
|
||||||
+ archive_entry_copy_pathname(ae, "dir1/");
|
|
||||||
+ archive_entry_set_mode(ae, AE_IFDIR | 0555);
|
|
||||||
+ assertEqualIntA(ad, 0, archive_write_header(ad, ae));
|
|
||||||
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
|
||||||
+ archive_entry_free(ae);
|
|
||||||
+
|
|
||||||
+ /* Directory: dir2 */
|
|
||||||
assert((ae = archive_entry_new()) != NULL);
|
|
||||||
- archive_entry_copy_pathname(ae, "dir");
|
|
||||||
- archive_entry_set_mode(ae, AE_IFDIR | 0606);
|
|
||||||
+ archive_entry_copy_pathname(ae, "dir2/");
|
|
||||||
+ archive_entry_set_mode(ae, AE_IFDIR | 0555);
|
|
||||||
assertEqualIntA(ad, 0, archive_write_header(ad, ae));
|
|
||||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
|
||||||
archive_entry_free(ae);
|
|
||||||
|
|
||||||
- /* Symbolic Link: dir -> foo */
|
|
||||||
+ /* Symbolic Link: dir1 -> dir */
|
|
||||||
+ assert((ae = archive_entry_new()) != NULL);
|
|
||||||
+ archive_entry_copy_pathname(ae, "dir1");
|
|
||||||
+ archive_entry_set_mode(ae, AE_IFLNK | 0777);
|
|
||||||
+ archive_entry_set_size(ae, 0);
|
|
||||||
+ archive_entry_copy_symlink(ae, "dir");
|
|
||||||
+ assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
|
||||||
+ if (r >= ARCHIVE_WARN)
|
|
||||||
+ assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
|
||||||
+ archive_entry_free(ae);
|
|
||||||
+
|
|
||||||
+ /* Symbolic Link: dir2 -> file */
|
|
||||||
assert((ae = archive_entry_new()) != NULL);
|
|
||||||
- archive_entry_copy_pathname(ae, "dir");
|
|
||||||
+ archive_entry_copy_pathname(ae, "dir2");
|
|
||||||
archive_entry_set_mode(ae, AE_IFLNK | 0777);
|
|
||||||
archive_entry_set_size(ae, 0);
|
|
||||||
- archive_entry_copy_symlink(ae, "victim");
|
|
||||||
+ archive_entry_copy_symlink(ae, "file");
|
|
||||||
assertEqualIntA(ad, 0, r = archive_write_header(ad, ae));
|
|
||||||
if (r >= ARCHIVE_WARN)
|
|
||||||
assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
|
|
||||||
@@ -75,6 +99,8 @@ DEFINE_TEST(test_write_disk_fixup)
|
|
||||||
assertEqualInt(ARCHIVE_OK, archive_write_free(ad));
|
|
||||||
|
|
||||||
/* Test the entries on disk. */
|
|
||||||
- assertIsSymlink("dir", "victim");
|
|
||||||
- assertFileMode("victim", 0600);
|
|
||||||
+ assertIsSymlink("dir1", "dir");
|
|
||||||
+ assertIsSymlink("dir2", "file");
|
|
||||||
+ assertFileMode("dir", 0700);
|
|
||||||
+ assertFileMode("file", 0600);
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
||||||
From ede459d2ebb879f5eedb6f7abea203be0b334230 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Martin Matuska <martin@matuska.org>
|
|
||||||
Date: Wed, 17 Nov 2021 21:06:00 +0100
|
|
||||||
Subject: [PATCH] archive_write_disk_posix: fix writing fflags broken in
|
|
||||||
8a1bd5c
|
|
||||||
|
|
||||||
The fixup list was erroneously assumed to be directories only.
|
|
||||||
Only in the case of critical file flags modification (e.g. SF_IMMUTABLE
|
|
||||||
on BSD systems), other file types (e.g. regular files or symbolic links)
|
|
||||||
may be added to the fixup list. We still need to verify that we are writing
|
|
||||||
to the correct file type, so compare the archive entry file type with
|
|
||||||
the file type of the file to be modified.
|
|
||||||
|
|
||||||
Fixes #1617
|
|
||||||
---
|
|
||||||
libarchive/archive_write_disk_posix.c | 87 +++++++++++++++++++++++----
|
|
||||||
1 file changed, 75 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
|
|
||||||
index aadc5871..7e57aac2 100644
|
|
||||||
--- a/libarchive/archive_write_disk_posix.c
|
|
||||||
+++ b/libarchive/archive_write_disk_posix.c
|
|
||||||
@@ -173,6 +173,7 @@ struct fixup_entry {
|
|
||||||
struct fixup_entry *next;
|
|
||||||
struct archive_acl acl;
|
|
||||||
mode_t mode;
|
|
||||||
+ __LA_MODE_T filetype;
|
|
||||||
int64_t atime;
|
|
||||||
int64_t birthtime;
|
|
||||||
int64_t mtime;
|
|
||||||
@@ -357,6 +358,7 @@ struct archive_write_disk {
|
|
||||||
|
|
||||||
#define HFS_BLOCKS(s) ((s) >> 12)
|
|
||||||
|
|
||||||
+static int la_verify_filetype(mode_t, __LA_MODE_T);
|
|
||||||
static void fsobj_error(int *, struct archive_string *, int, const char *,
|
|
||||||
const char *);
|
|
||||||
static int check_symlinks_fsobj(char *, int *, struct archive_string *,
|
|
||||||
@@ -464,6 +466,39 @@ la_opendirat(int fd, const char *path) {
|
|
||||||
static ssize_t _archive_write_disk_data_block(struct archive *, const void *,
|
|
||||||
size_t, int64_t);
|
|
||||||
|
|
||||||
+static int
|
|
||||||
+la_verify_filetype(mode_t mode, __LA_MODE_T filetype) {
|
|
||||||
+ int ret = 0;
|
|
||||||
+
|
|
||||||
+ switch (filetype) {
|
|
||||||
+ case AE_IFREG:
|
|
||||||
+ ret = (S_ISREG(mode));
|
|
||||||
+ break;
|
|
||||||
+ case AE_IFDIR:
|
|
||||||
+ ret = (S_ISDIR(mode));
|
|
||||||
+ break;
|
|
||||||
+ case AE_IFLNK:
|
|
||||||
+ ret = (S_ISLNK(mode));
|
|
||||||
+ break;
|
|
||||||
+ case AE_IFSOCK:
|
|
||||||
+ ret = (S_ISSOCK(mode));
|
|
||||||
+ break;
|
|
||||||
+ case AE_IFCHR:
|
|
||||||
+ ret = (S_ISCHR(mode));
|
|
||||||
+ break;
|
|
||||||
+ case AE_IFBLK:
|
|
||||||
+ ret = (S_ISBLK(mode));
|
|
||||||
+ break;
|
|
||||||
+ case AE_IFIFO:
|
|
||||||
+ ret = (S_ISFIFO(mode));
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return (ret);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int
|
|
||||||
lazy_stat(struct archive_write_disk *a)
|
|
||||||
{
|
|
||||||
@@ -822,6 +857,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
|
||||||
fe = current_fixup(a, archive_entry_pathname(entry));
|
|
||||||
if (fe == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
+ fe->filetype = archive_entry_filetype(entry);
|
|
||||||
fe->fixup |= TODO_MODE_BASE;
|
|
||||||
fe->mode = a->mode;
|
|
||||||
}
|
|
||||||
@@ -832,6 +868,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
|
||||||
fe = current_fixup(a, archive_entry_pathname(entry));
|
|
||||||
if (fe == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
+ fe->filetype = archive_entry_filetype(entry);
|
|
||||||
fe->mode = a->mode;
|
|
||||||
fe->fixup |= TODO_TIMES;
|
|
||||||
if (archive_entry_atime_is_set(entry)) {
|
|
||||||
@@ -865,6 +902,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
|
||||||
fe = current_fixup(a, archive_entry_pathname(entry));
|
|
||||||
if (fe == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
+ fe->filetype = archive_entry_filetype(entry);
|
|
||||||
fe->fixup |= TODO_ACLS;
|
|
||||||
archive_acl_copy(&fe->acl, archive_entry_acl(entry));
|
|
||||||
}
|
|
||||||
@@ -877,6 +915,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
|
||||||
fe = current_fixup(a, archive_entry_pathname(entry));
|
|
||||||
if (fe == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
+ fe->filetype = archive_entry_filetype(entry);
|
|
||||||
fe->mac_metadata = malloc(metadata_size);
|
|
||||||
if (fe->mac_metadata != NULL) {
|
|
||||||
memcpy(fe->mac_metadata, metadata,
|
|
||||||
@@ -891,6 +930,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
|
|
||||||
fe = current_fixup(a, archive_entry_pathname(entry));
|
|
||||||
if (fe == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
+ fe->filetype = archive_entry_filetype(entry);
|
|
||||||
fe->fixup |= TODO_FFLAGS;
|
|
||||||
/* TODO: Complete this.. defer fflags from below. */
|
|
||||||
}
|
|
||||||
@@ -2463,7 +2503,7 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
struct fixup_entry *next, *p;
|
|
||||||
struct stat st;
|
|
||||||
char *c;
|
|
||||||
- int fd, ret;
|
|
||||||
+ int fd, ret, openflags;
|
|
||||||
|
|
||||||
archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
|
|
||||||
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
|
|
||||||
@@ -2490,32 +2530,53 @@ _archive_write_disk_close(struct archive *_a)
|
|
||||||
if (p->fixup == 0)
|
|
||||||
goto skip_fixup_entry;
|
|
||||||
else {
|
|
||||||
- fd = open(p->name, O_BINARY | O_NOFOLLOW | O_RDONLY
|
|
||||||
+ /*
|
|
||||||
+ * We need to verify if the type of the file
|
|
||||||
+ * we are going to open matches the file type
|
|
||||||
+ * of the fixup entry.
|
|
||||||
+ */
|
|
||||||
+ openflags = O_BINARY | O_NOFOLLOW | O_RDONLY
|
|
||||||
+ | O_CLOEXEC;
|
|
||||||
#if defined(O_DIRECTORY)
|
|
||||||
- | O_DIRECTORY
|
|
||||||
+ if (p->filetype == AE_IFDIR)
|
|
||||||
+ openflags |= O_DIRECTORY;
|
|
||||||
#endif
|
|
||||||
- | O_CLOEXEC);
|
|
||||||
+ fd = open(p->name, openflags);
|
|
||||||
+
|
|
||||||
+#if defined(O_DIRECTORY)
|
|
||||||
/*
|
|
||||||
- ` * If we don't support O_DIRECTORY,
|
|
||||||
- * or open() has failed, we must stat()
|
|
||||||
- * to verify that we are opening a directory
|
|
||||||
+ * If we support O_DIRECTORY and open was
|
|
||||||
+ * successful we can skip the file type check
|
|
||||||
+ * for directories. For other file types
|
|
||||||
+ * we need to verify via fstat() or lstat()
|
|
||||||
*/
|
|
||||||
-#if defined(O_DIRECTORY)
|
|
||||||
- if (fd == -1) {
|
|
||||||
+ if (fd == -1 || p->filetype != AE_IFDIR) {
|
|
||||||
+#if HAVE_FSTAT
|
|
||||||
+ if (fd > 0 && (
|
|
||||||
+ fstat(fd, &st) != 0 ||
|
|
||||||
+ la_verify_filetype(st.st_mode,
|
|
||||||
+ p->filetype) == 0)) {
|
|
||||||
+ goto skip_fixup_entry;
|
|
||||||
+ } else
|
|
||||||
+#endif
|
|
||||||
if (lstat(p->name, &st) != 0 ||
|
|
||||||
- !S_ISDIR(st.st_mode)) {
|
|
||||||
+ la_verify_filetype(st.st_mode,
|
|
||||||
+ p->filetype) == 0) {
|
|
||||||
goto skip_fixup_entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#if HAVE_FSTAT
|
|
||||||
if (fd > 0 && (
|
|
||||||
- fstat(fd, &st) != 0 || !S_ISDIR(st.st_mode))) {
|
|
||||||
+ fstat(fd, &st) != 0 ||
|
|
||||||
+ la_verify_filetype(st.st_mode,
|
|
||||||
+ p->filetype) == 0)) {
|
|
||||||
goto skip_fixup_entry;
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
if (lstat(p->name, &st) != 0 ||
|
|
||||||
- !S_ISDIR(st.st_mode)) {
|
|
||||||
+ la_verify_filetype(st.st_mode,
|
|
||||||
+ p->filetype) == 0) {
|
|
||||||
goto skip_fixup_entry;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -2689,6 +2750,7 @@ new_fixup(struct archive_write_disk *a, const char *pathname)
|
|
||||||
fe->next = a->fixup_list;
|
|
||||||
a->fixup_list = fe;
|
|
||||||
fe->fixup = 0;
|
|
||||||
+ fe->filetype = 0;
|
|
||||||
fe->name = strdup(pathname);
|
|
||||||
return (fe);
|
|
||||||
}
|
|
||||||
@@ -3811,6 +3873,7 @@ set_fflags(struct archive_write_disk *a)
|
|
||||||
le = current_fixup(a, a->name);
|
|
||||||
if (le == NULL)
|
|
||||||
return (ARCHIVE_FATAL);
|
|
||||||
+ le->filetype = archive_entry_filetype(a->entry);
|
|
||||||
le->fixup |= TODO_FFLAGS;
|
|
||||||
le->fflags_set = set;
|
|
||||||
/* Store the mode if it's not already there. */
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
From bff38efe8c110469c5080d387bec62a6ca15b1a5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: obiwac <obiwac@gmail.com>
|
|
||||||
Date: Fri, 22 Jul 2022 22:41:10 +0200
|
|
||||||
Subject: [PATCH] libarchive: Handle a `calloc` returning NULL (fixes #1754)
|
|
||||||
|
|
||||||
---
|
|
||||||
libarchive/archive_write.c | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
|
|
||||||
index 66592e82..27626b54 100644
|
|
||||||
--- a/libarchive/archive_write.c
|
|
||||||
+++ b/libarchive/archive_write.c
|
|
||||||
@@ -211,6 +211,10 @@ __archive_write_allocate_filter(struct a
|
|
||||||
struct archive_write_filter *f;
|
|
||||||
|
|
||||||
f = calloc(1, sizeof(*f));
|
|
||||||
+
|
|
||||||
+ if (f == NULL)
|
|
||||||
+ return (NULL);
|
|
||||||
+
|
|
||||||
f->archive = _a;
|
|
||||||
if (a->filter_first == NULL)
|
|
||||||
a->filter_first = f;
|
|
||||||
@@ -548,6 +552,10 @@ archive_write_open2(struct archive *_a, void *client_data,
|
|
||||||
a->client_data = client_data;
|
|
||||||
|
|
||||||
client_filter = __archive_write_allocate_filter(_a);
|
|
||||||
+
|
|
||||||
+ if (client_filter == NULL)
|
|
||||||
+ return (ARCHIVE_FATAL);
|
|
||||||
+
|
|
||||||
client_filter->open = archive_write_client_open;
|
|
||||||
client_filter->write = archive_write_client_write;
|
|
||||||
client_filter->close = archive_write_client_close;
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
|||||||
From afef3d7fc131df0dac09a46b8673898860a193db Mon Sep 17 00:00:00 2001
|
|
||||||
From: Zdenek Zambersky <zzambers@redhat.com>
|
|
||||||
Date: Tue, 11 Jan 2022 14:43:27 +0100
|
|
||||||
Subject: [PATCH] Fixed size filed in pax header
|
|
||||||
|
|
||||||
---
|
|
||||||
libarchive/archive_write_set_format_pax.c | 10 +++++++---
|
|
||||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/archive_write_set_format_pax.c b/libarchive/archive_write_set_format_pax.c
|
|
||||||
index a2b27107..52911491 100644
|
|
||||||
--- a/libarchive/archive_write_set_format_pax.c
|
|
||||||
+++ b/libarchive/archive_write_set_format_pax.c
|
|
||||||
@@ -1028,10 +1028,8 @@ archive_write_pax_header(struct archive_write *a,
|
|
||||||
archive_string_init(&entry_name);
|
|
||||||
archive_strcpy(&entry_name, archive_entry_pathname(entry_main));
|
|
||||||
|
|
||||||
- /* If file size is too large, add 'size' to pax extended attrs. */
|
|
||||||
+ /* If file size is too large, we need pax extended attrs. */
|
|
||||||
if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
|
|
||||||
- add_pax_attr_int(&(pax->pax_header), "size",
|
|
||||||
- archive_entry_size(entry_main));
|
|
||||||
need_extension = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1347,6 +1345,12 @@ archive_write_pax_header(struct archive_write *a,
|
|
||||||
mapsize + pax->sparse_map_padding + sparse_total);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* If file size is too large, add 'size' to pax extended attrs. */
|
|
||||||
+ if (archive_entry_size(entry_main) >= (((int64_t)1) << 33)) {
|
|
||||||
+ add_pax_attr_int(&(pax->pax_header), "size",
|
|
||||||
+ archive_entry_size(entry_main));
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* Format 'ustar' header for main entry.
|
|
||||||
*
|
|
||||||
* The trouble with file size: If the reader can't understand
|
|
||||||
--
|
|
||||||
2.34.3
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
|||||||
From 1bb2ec24b433bf87fed40e207c61c6aa8790e793 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Ondrej Dubaj <odubaj@redhat.com>
|
|
||||||
Date: Mon, 18 Nov 2019 12:41:07 +0100
|
|
||||||
Subject: [PATCH] test_write_filter_zstd: size @ lvl=20 < default < lvl=1
|
|
||||||
|
|
||||||
Raise compression on the second test to level=20, and perform a
|
|
||||||
third at level=1. Expect the output archive sizes to line up
|
|
||||||
based on compression level. Reduces test susceptibility to small
|
|
||||||
output size variations from different libzstd releases.
|
|
||||||
---
|
|
||||||
libarchive/test/test_write_filter_zstd.c | 66 +++++++++++++++++--
|
|
||||||
1 file changed, 60 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/libarchive/test/test_write_filter_zstd.c b/libarchive/test/test_write_filter_zstd.c
|
|
||||||
index da3c806..13de134 100644
|
|
||||||
--- a/libarchive/test/test_write_filter_zstd.c
|
|
||||||
+++ b/libarchive/test/test_write_filter_zstd.c
|
|
||||||
@@ -34,7 +34,7 @@ DEFINE_TEST(test_write_filter_zstd)
|
|
||||||
char *buff, *data;
|
|
||||||
size_t buffsize, datasize;
|
|
||||||
char path[16];
|
|
||||||
- size_t used1, used2;
|
|
||||||
+ size_t used1, used2, used3;
|
|
||||||
int i, r;
|
|
||||||
|
|
||||||
buffsize = 2000000;
|
|
||||||
@@ -125,7 +125,7 @@ DEFINE_TEST(test_write_filter_zstd)
|
|
||||||
assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
archive_write_set_filter_option(a, NULL, "compression-level", "9"));
|
|
||||||
assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
- archive_write_set_filter_option(a, NULL, "compression-level", "6"));
|
|
||||||
+ archive_write_set_filter_option(a, NULL, "compression-level", "20"));
|
|
||||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2));
|
|
||||||
for (i = 0; i < 100; i++) {
|
|
||||||
sprintf(path, "file%03d", i);
|
|
||||||
@@ -140,10 +140,6 @@ DEFINE_TEST(test_write_filter_zstd)
|
|
||||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
|
||||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
|
||||||
|
|
||||||
- failure("compression-level=6 wrote %d bytes, default wrote %d bytes",
|
|
||||||
- (int)used2, (int)used1);
|
|
||||||
- assert(used2 < used1);
|
|
||||||
-
|
|
||||||
assert((a = archive_read_new()) != NULL);
|
|
||||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
|
||||||
r = archive_read_support_filter_zstd(a);
|
|
||||||
@@ -167,6 +163,64 @@ DEFINE_TEST(test_write_filter_zstd)
|
|
||||||
}
|
|
||||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * One more time at level 1
|
|
||||||
+ */
|
|
||||||
+ assert((a = archive_write_new()) != NULL);
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
+ archive_write_set_bytes_per_block(a, 10));
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a));
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
+ archive_write_set_filter_option(a, NULL, "compression-level", "1"));
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used3));
|
|
||||||
+ assert((ae = archive_entry_new()) != NULL);
|
|
||||||
+ archive_entry_set_filetype(ae, AE_IFREG);
|
|
||||||
+ archive_entry_set_size(ae, datasize);
|
|
||||||
+ for (i = 0; i < 100; i++) {
|
|
||||||
+ sprintf(path, "file%03d", i);
|
|
||||||
+ archive_entry_copy_pathname(ae, path);
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
|
||||||
+ assertA(datasize == (size_t)archive_write_data(a, data, datasize));
|
|
||||||
+ }
|
|
||||||
+ archive_entry_free(ae);
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
|
|
||||||
+ assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
|
||||||
+
|
|
||||||
+ assert((a = archive_read_new()) != NULL);
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
|
||||||
+ r = archive_read_support_filter_zstd(a);
|
|
||||||
+ if (r == ARCHIVE_WARN) {
|
|
||||||
+ skipping("zstd reading not fully supported on this platform");
|
|
||||||
+ } else {
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
+ archive_read_support_filter_all(a));
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
+ archive_read_open_memory(a, buff, used3));
|
|
||||||
+ for (i = 0; i < 100; i++) {
|
|
||||||
+ sprintf(path, "file%03d", i);
|
|
||||||
+ failure("Trying to read %s", path);
|
|
||||||
+ if (!assertEqualIntA(a, ARCHIVE_OK,
|
|
||||||
+ archive_read_next_header(a, &ae)))
|
|
||||||
+ break;
|
|
||||||
+ assertEqualString(path, archive_entry_pathname(ae));
|
|
||||||
+ assertEqualInt((int)datasize, archive_entry_size(ae));
|
|
||||||
+ }
|
|
||||||
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
|
||||||
+ }
|
|
||||||
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Check output sizes for various compression levels, expectation
|
|
||||||
+ * is that archive size for level=20 < default < level=1
|
|
||||||
+ */
|
|
||||||
+ failure("compression-level=20 wrote %d bytes, default wrote %d bytes",
|
|
||||||
+ (int)used2, (int)used1);
|
|
||||||
+ assert(used2 < used1);
|
|
||||||
+ failure("compression-level=1 wrote %d bytes, default wrote %d bytes",
|
|
||||||
+ (int)used3, (int)used1);
|
|
||||||
+ assert(used1 < used3);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Test various premature shutdown scenarios to make sure we
|
|
||||||
* don't crash or leak memory.
|
|
||||||
--
|
|
||||||
2.19.1
|
|
||||||
|
|
@ -1,49 +1,60 @@
|
|||||||
%bcond_without check
|
%bcond_without check
|
||||||
|
|
||||||
Name: libarchive
|
Name: libarchive
|
||||||
Version: 3.3.3
|
Version: 3.7.2
|
||||||
Release: 5%{?dist}
|
Release: 7%{?dist}
|
||||||
Summary: A library for handling streaming archive formats
|
Summary: A library for handling streaming archive formats
|
||||||
|
|
||||||
License: BSD
|
# Licenses:
|
||||||
URL: http://www.libarchive.org/
|
# ./configure: FSFUL
|
||||||
Source0: http://www.libarchive.org/downloads/%{name}-%{version}.tar.gz
|
# ./build/autoconf/lib-ld.m4: FSFULLR
|
||||||
|
# ./configure: FSFUL
|
||||||
|
# ./unzip/la_queue.h: BSD-3-Clause
|
||||||
|
# ./aclocal.m4: (FSFULLR and/or GPL-2) with Libtool-exception exception
|
||||||
|
License: BSD-2-Clause AND FSFULLR AND GPL-2.0-or-later WITH Libtool-exception AND BSD-3-Clause AND FSFUL
|
||||||
|
URL: https://www.libarchive.org/
|
||||||
|
Source0: https://libarchive.org/downloads/%{name}-%{version}.tar.gz
|
||||||
|
|
||||||
Patch1: libarchive-3.1.2-CVE-2019-1000019.patch
|
BuildRequires: autoconf
|
||||||
Patch2: libarchive-3.1.2-CVE-2019-1000020.patch
|
BuildRequires: automake
|
||||||
Patch3: libarchive-3.3.2-CVE-2018-1000878.patch
|
|
||||||
Patch4: libarchive-3.3.2-CVE-2018-1000877.patch
|
|
||||||
Patch5: fix-use-after-free-in-delayed-newc.patch
|
|
||||||
Patch6: fix-few-obvious-resource-leaks-covscan.patch
|
|
||||||
Patch7: libarchive-3.3.2-CVE-2019-18408.patch
|
|
||||||
Patch8: libarchive-3.3.2-CVE-2019-19221.patch
|
|
||||||
# upstream reference
|
|
||||||
# https://github.com/libarchive/libarchive/commit/aaacc8762fd8ced8823350edd8ce2e46b565582b#diff-bc144884a8e634e16f247e0588a266ee
|
|
||||||
Patch9: libarchive-3.3.3-fixed-zstd_test.patch
|
|
||||||
Patch10: libarchive-3.3.3-CVE-2021-23177.patch
|
|
||||||
Patch11: libarchive-3.3.3-CVE-2021-31566.patch
|
|
||||||
# Source: https://github.com/libarchive/libarchive/commit/b1b501161013296d19dfe9acb84a341c8a1755b9
|
|
||||||
Patch12: %{name}-3.3.3-Fix-size-filed-in-pax-header.patch
|
|
||||||
Patch13: %{name}-3.3.3-Fix-CVE-2022-36227.patch
|
|
||||||
|
|
||||||
|
|
||||||
BuildRequires: gcc
|
|
||||||
BuildRequires: bison
|
BuildRequires: bison
|
||||||
BuildRequires: sharutils
|
|
||||||
BuildRequires: zlib-devel
|
|
||||||
BuildRequires: bzip2-devel
|
BuildRequires: bzip2-devel
|
||||||
BuildRequires: xz-devel
|
|
||||||
BuildRequires: lzo-devel
|
|
||||||
BuildRequires: e2fsprogs-devel
|
BuildRequires: e2fsprogs-devel
|
||||||
|
BuildRequires: gcc
|
||||||
BuildRequires: libacl-devel
|
BuildRequires: libacl-devel
|
||||||
BuildRequires: libattr-devel
|
BuildRequires: libattr-devel
|
||||||
BuildRequires: openssl-devel
|
|
||||||
BuildRequires: libxml2-devel
|
|
||||||
BuildRequires: lz4-devel
|
|
||||||
BuildRequires: automake
|
|
||||||
BuildRequires: libzstd-devel
|
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
|
BuildRequires: libxml2-devel
|
||||||
|
BuildRequires: libzstd-devel
|
||||||
|
BuildRequires: lz4-devel
|
||||||
|
# According to libarchive maintainer, linking against liblzo violates
|
||||||
|
# LZO license.
|
||||||
|
# See https://github.com/libarchive/libarchive/releases/tag/v3.3.0
|
||||||
|
#BuildRequires: lzo-devel
|
||||||
|
BuildRequires: openssl-devel
|
||||||
|
BuildRequires: sharutils
|
||||||
|
BuildRequires: xz-devel
|
||||||
|
BuildRequires: zlib-devel
|
||||||
|
BuildRequires: make
|
||||||
|
|
||||||
|
# When configured against OpenSSL 1.1, the RIPEMD-160 support was not detected,
|
||||||
|
# so it was not compiled in previously. With OpenSSL 3.0, it's now detected as
|
||||||
|
# being available, but it only actually works when the legacy provider is
|
||||||
|
# loaded, which breaks the RIPEMD-160 test. This patch disables the RIPEMD-160
|
||||||
|
# support explicitly.
|
||||||
|
Patch0001: 0001-Drop-rmd160-from-OpenSSL.patch
|
||||||
|
|
||||||
|
# Upstream patch: https://github.com/libarchive/libarchive/commit/3bd918d92f8c34ba12de9c6604d96f9e262a59fc
|
||||||
|
# Fixes the broken 32-bit builds (i686 arch) due to "Allocation error : not enough memory"
|
||||||
|
Patch0002: 0002-tests-fix-zstd-long-option-test-for-32-bit-architect.patch
|
||||||
|
|
||||||
|
# Upstream patch: https://github.com/libarchive/libarchive/commit/eb7939b24a681a04648a59cdebd386b1e9dc9237
|
||||||
|
# Fixes Heap based buffer overflow in rar e8 filter (CVE-2024-26256)
|
||||||
|
Patch0003: 0003-fix-OOB-in-rar-e8-filter.patch
|
||||||
|
|
||||||
|
# Upstream patch: https://github.com/libarchive/libarchive/commit/eac15e252010c1189a5c0f461364dbe2cd2a68b1
|
||||||
|
# Fixes CVE-2024-20696
|
||||||
|
Patch0004: 0004-rar4-reader-protect-copy_from_lzss_window_to_unp-217.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Libarchive is a programming library that can create and read several different
|
Libarchive is a programming library that can create and read several different
|
||||||
@ -88,23 +99,27 @@ The bsdcat program typically takes a filename as an argument or reads standard
|
|||||||
input when used in a pipe. In both cases decompressed data it written to
|
input when used in a pipe. In both cases decompressed data it written to
|
||||||
standard output.
|
standard output.
|
||||||
|
|
||||||
|
%package -n bsdunzip
|
||||||
|
Summary: Extract files from a ZIP archive
|
||||||
|
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||||
|
|
||||||
|
%description -n bsdunzip
|
||||||
|
The bsdunzip package contains standalone bsdunzip utility split off regular
|
||||||
|
libarchive packages. It is designed to provide an interface compatible with Info-ZIP's.
|
||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -p1
|
%autosetup -p1
|
||||||
bash build/autogen.sh
|
|
||||||
|
|
||||||
|
|
||||||
%build
|
%build
|
||||||
%configure --disable-static --disable-rpath
|
autoreconf -ifv
|
||||||
# remove rpaths
|
%configure --disable-static LT_SYS_LIBRARY_PATH=%_libdir
|
||||||
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
|
%make_build
|
||||||
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
|
|
||||||
|
|
||||||
make %{?_smp_mflags}
|
|
||||||
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
make install DESTDIR=$RPM_BUILD_ROOT
|
%make_install
|
||||||
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
||||||
|
|
||||||
# rhbz#1294252
|
# rhbz#1294252
|
||||||
@ -166,7 +181,7 @@ cat_logs ()
|
|||||||
run_testsuite ()
|
run_testsuite ()
|
||||||
{
|
{
|
||||||
rc=0
|
rc=0
|
||||||
LD_LIBRARY_PATH=`pwd`/.libs make %{?_smp_mflags} check -j1 || {
|
%make_build check -j1 || {
|
||||||
# error happened - try to extract in koji as much info as possible
|
# error happened - try to extract in koji as much info as possible
|
||||||
cat_logs
|
cat_logs
|
||||||
|
|
||||||
@ -229,45 +244,143 @@ run_testsuite
|
|||||||
%{_bindir}/bsdcat
|
%{_bindir}/bsdcat
|
||||||
%{_mandir}/*/bsdcat*
|
%{_mandir}/*/bsdcat*
|
||||||
|
|
||||||
|
%files -n bsdunzip
|
||||||
|
%{!?_licensedir:%global license %%doc}
|
||||||
|
%license COPYING
|
||||||
|
%doc NEWS README.md
|
||||||
|
%{_bindir}/bsdunzip
|
||||||
|
%{_mandir}/*/bsdunzip*
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Tue Dec 06 2022 Lukas Javorsky <ljavorsk@redhat.com> - 3.3.3-5
|
* Mon Jun 24 2024 Troy Dawson <tdawson@redhat.com> - 3.7.2-7
|
||||||
- Fix for CVE-2022-36227
|
- Bump release for June 2024 mass rebuild
|
||||||
|
|
||||||
* Tue Jul 12 2022 Lukas Javorsky <ljavorsk@redhat.com> - 3.3.3-4
|
* Thu Jun 06 2024 Lukas Javorsky <ljavorsk@redhat.com> - 3.7.2-6
|
||||||
- Resolves: #2037839
|
- Fix CVE-2024-20696
|
||||||
|
- Resolves: RHEL-40042
|
||||||
|
|
||||||
* Tue Dec 21 2021 Matej Mužila <mmuzila@redhat.com> - 3.3.3-3
|
* Mon May 27 2024 Lukas Javorsky <ljavorsk@redhat.com> - 3.7.2-5
|
||||||
- Do not follow symlinks when processing the fixup list (CVE-2021-31566)
|
- Fix for CVE-2024-26256
|
||||||
|
|
||||||
* Mon Dec 20 2021 Matej Mužila <mmuzila@redhat.com> - 3.3.3-2
|
* Tue May 14 2024 Lukas Javorsky <ljavorsk@redhat.com> - 3.7.2-4
|
||||||
- Fix handling of symbolic link ACLs (CVE-2021-23177)
|
- Add forgotten licenses and migrate them to SPDX format
|
||||||
|
|
||||||
* Thu Apr 30 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.3.3-1
|
* Thu Jan 25 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.7.2-3
|
||||||
- Rebase to version 3.3.3
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||||
|
|
||||||
* Tue Mar 24 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.3.2-9
|
* Sun Jan 21 2024 Fedora Release Engineering <releng@fedoraproject.org> - 3.7.2-2
|
||||||
- Fix out-of-bounds read (CVE-2019-19221) (#1803967)
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
|
||||||
|
|
||||||
* Wed Jan 15 2020 Patrik Novotný <panovotn@redhat.com> - 3.3.2-8
|
* Tue Sep 12 2023 Lukas Javorsky <ljavorsk@redhat.com> - 3.7.2-1
|
||||||
- Fix CVE-2019-18408: RAR use-after-free
|
- Rebase to version 3.7.2
|
||||||
|
|
||||||
* Mon May 27 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.3.2-7
|
* Mon Jul 31 2023 Lukas Javorsky <ljavorsk@redhat.com> - 3.7.1-1
|
||||||
- fix use-after-free in delayed newc link processing (#1602575)
|
- Rebase to version 3.7.1
|
||||||
- fix a few obvious resource leaks and strcpy() misuses (#1602575)
|
|
||||||
|
|
||||||
* Tue Apr 30 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.3.2-6
|
* Tue Jul 25 2023 Lukas Javorsky <ljavorsk@redhat.com> - 3.7.0-1
|
||||||
- fixed use after free in RAR decoder (#1700752)
|
- Rebase to version 3.7.0
|
||||||
- fixed double free in RAR decoder (#1700753)
|
- Add new bsdunzip subpackage
|
||||||
|
|
||||||
* Tue Apr 02 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.3.2-5
|
* Thu Jul 20 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.6.1-6
|
||||||
- release bump due to gating (#1680768)
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
|
||||||
|
|
||||||
* Fri Feb 22 2019 Pavel Raiskup <praiskup@redhat.com> - 3.3.2-4
|
* Wed Feb 08 2023 Davide Cavalca <dcavalca@fedoraproject.org> - 3.6.1-5
|
||||||
- fix out-of-bounds read within lha_read_data_none() (CVE-2017-14503)
|
- Backport upstream PR#1772 for better pathname portability across OS
|
||||||
- fix crash on crafted 7zip archives (CVE-2019-1000019)
|
Resolves: #2136961
|
||||||
- fix infinite loop in ISO9660 (CVE-2019-1000020)
|
|
||||||
|
* Thu Jan 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 3.6.1-4
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
|
||||||
|
|
||||||
|
* Fri Dec 02 2022 Lukas Javorsky <ljavorsk@redhat.com> - 3.6.1-3
|
||||||
|
- Resolves: CVE-2022-36227
|
||||||
|
|
||||||
|
* Thu Jul 21 2022 Fedora Release Engineering <releng@fedoraproject.org> - 3.6.1-2
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
|
||||||
|
|
||||||
|
* Fri Apr 08 2022 Lukas Javorsky <ljavorsk@redhat.com> - 3.6.1-1
|
||||||
|
- Rebase to version 3.6.1
|
||||||
|
- Resolves: #2071934
|
||||||
|
|
||||||
|
* Tue Feb 22 2022 Matej Mužila <mmuzila@redhat.com> - 3.6.0-1
|
||||||
|
- Rebase to version 3.6.0
|
||||||
|
- Resolves: #2051860
|
||||||
|
|
||||||
|
* Mon Feb 14 2022 Lukas Javorsky <ljavorsk@redhat.com> - 3.5.3-1
|
||||||
|
- Rebase to version 3.5.3
|
||||||
|
|
||||||
|
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 3.5.2-5
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild
|
||||||
|
|
||||||
|
* Fri Dec 03 2021 Stephen Gallagher <sgallagh@redhat.com> - 3.5.2-5
|
||||||
|
- Drop RIPEMD-160 support for OpenSSL 3.0
|
||||||
|
|
||||||
|
* Tue Sep 14 2021 Sahana Prasad <sahana@redhat.com> - 3.5.2-3
|
||||||
|
- Rebuilt with OpenSSL 3.0.0
|
||||||
|
|
||||||
|
* Mon Aug 30 2021 Ondrej Dubaj <odubaj@redhat.com> - 3.5.2-2
|
||||||
|
- Fixed symlink handling
|
||||||
|
|
||||||
|
* Mon Aug 23 2021 Ondrej Dubaj <odubaj@redhat.com> - 3.5.2-1
|
||||||
|
- Rebased to version 3.5.2
|
||||||
|
|
||||||
|
* Thu Jul 22 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.5.1-3
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
|
||||||
|
|
||||||
|
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.5.1-2
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||||
|
|
||||||
|
* Mon Jan 04 2021 Ondrej Dubaj <odubaj@redhat.com> - 3.5.1-1
|
||||||
|
- Rebased to version 3.5.1
|
||||||
|
|
||||||
|
* Wed Dec 02 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.5.0-1
|
||||||
|
- Rebased to version 3.5.0
|
||||||
|
|
||||||
|
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.4.3-3
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||||
|
|
||||||
|
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 3.4.3-2
|
||||||
|
- Use make macros
|
||||||
|
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
|
||||||
|
|
||||||
|
* Fri May 22 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.4.3-1
|
||||||
|
- Rebased to version 3.4.3
|
||||||
|
|
||||||
|
* Wed Feb 12 2020 Ondrej Dubaj <odubaj@redhat.com> - 3.4.2-1
|
||||||
|
- Rebased to version 3.4.2
|
||||||
|
|
||||||
|
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.4.0-2
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
|
||||||
|
|
||||||
|
* Fri Aug 30 2019 FeRD (Frank Dana) <ferdnyc@gmail.com> - 3.4.0-1
|
||||||
|
- New upstream release, adds RAR5 and ZIPX support (readonly)
|
||||||
|
- Drop upstreamed patches
|
||||||
|
- Add upstreamed patch to fix test failure with libzstd-1.4.2
|
||||||
|
|
||||||
|
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.3.3-8
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||||
|
|
||||||
|
* Thu Mar 28 2019 Pavel Raiskup <praiskup@redhat.com> - 3.3.3-7
|
||||||
|
- simplify libtool hacks
|
||||||
|
|
||||||
|
* Tue Mar 19 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.3.3-6
|
||||||
|
- applied various flaws (#1663893)
|
||||||
|
|
||||||
|
* Tue Mar 19 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.3.3-5
|
||||||
|
- applied CVE patches (#1690071)
|
||||||
|
|
||||||
|
* Thu Mar 14 2019 Ondrej Dubaj <odubaj@redhat.com> - 3.3.3-4
|
||||||
|
- applied various flaws (#1672900)
|
||||||
|
|
||||||
|
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 3.3.3-3
|
||||||
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||||
|
|
||||||
|
* Mon Nov 26 2018 Pavel Raiskup <praiskup@redhat.com> - 3.3.3-2
|
||||||
|
- fix some covscan issues (rhbz#1602575)
|
||||||
|
- build-requires libzstd-devel (rhbz#1653046)
|
||||||
|
|
||||||
|
* Tue Oct 23 2018 Pavel Raiskup <praiskup@redhat.com> - 3.3.3-1
|
||||||
|
- the latest upstream release
|
||||||
|
|
||||||
* Wed Jul 18 2018 Pavel Raiskup <praiskup@redhat.com> - 3.3.2-3
|
* Wed Jul 18 2018 Pavel Raiskup <praiskup@redhat.com> - 3.3.2-3
|
||||||
- drop use of %%ldconfig_scriptlets
|
- drop use of %%ldconfig_scriptlets
|
Loading…
Reference in New Issue
Block a user