Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
fdb6339af5
!62 fix CVE-2024-20696
From: @ultra_planet 
Reviewed-by: @dillon_chen 
Signed-off-by: @dillon_chen
2024-06-07 08:48:07 +00:00
lingsheng
d58d949239 fix CVE-2024-20696 2024-06-06 09:17:28 +00:00
openeuler-ci-bot
d21d3abca8
!48 [sync] PR-45: fix CVE-2021-36976 patch
From: @openeuler-sync-bot 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
2023-03-09 07:59:18 +00:00
zhangpan
ea8d25748c fix CVE-2021-36976 patch
(cherry picked from commit 8c20b91ab38536f5e806ae2b7d17e1f497db66b2)
2023-03-08 11:33:37 +08:00
openeuler-ci-bot
eee309057e
!41 [sync] PR-40: fix CVE-2022-36227
From: @openeuler-sync-bot 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
2022-11-29 11:41:02 +00:00
wangkerong
7369be3acf fix CVE-2022-36227
(cherry picked from commit 10cec7ef4258335fa8a6cd6eb6a57dd12776d61e)
2022-11-28 09:31:12 +08:00
openeuler-ci-bot
ceee4222cb
!37 [sync] PR-35: fix CVE-2022-26280
From: @openeuler-sync-bot 
Reviewed-by: @yanan-rock 
Signed-off-by: @yanan-rock
2022-07-04 03:08:07 +00:00
wangkerong
efbbaa7d87 fix CVE-2022-26280
(cherry picked from commit 211f12ff0d59610d877e35df403a26782b28c296)
2022-07-04 10:40:58 +08:00
openeuler-ci-bot
5aef6a179f
!24 [sync] PR-21: fix CVE-2021-23177,CVE-2021-31566
Merge pull request !24 from openeuler-sync-bot/sync-pr21-openEuler-20.03-LTS-to-openEuler-20.03-LTS-SP3
2022-01-13 09:33:14 +00:00
yangcheng1203
9ac841e4ec fix cves
(cherry picked from commit c74dfd1372ea7c34088ef7854f08674dcfc48ee2)
2022-01-12 11:52:56 +08:00
12 changed files with 1160 additions and 59 deletions

View File

@ -0,0 +1,190 @@
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 d526daa..d227f81 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -556,6 +556,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 0168d0d..35b494c 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -2444,6 +2444,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,
@@ -2461,6 +2462,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,
@@ -2475,7 +2490,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,
@@ -2486,6 +2506,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);
@@ -2626,6 +2647,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 4be5bf4..5d6d8ce 100644
--- a/libarchive/test/CMakeLists.txt
+++ b/libarchive/test/CMakeLists.txt
@@ -208,6 +208,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 0000000..153cc3a
--- /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", 0);
+ assertFileMode("victim", 0600);
+}
--
2.23.0

View File

@ -0,0 +1,46 @@
From 29fd0178a8861af36ab60407cd718b3f262dda15 Mon Sep 17 00:00:00 2001
From: Emil Velikov <emil.l.velikov@gmail.com>
Date: Sun, 21 Nov 2021 18:05:19 +0000
Subject: [PATCH] tar: demote -xa from error to a warning
It's fairly common for people to use caf and xaf on Linux. The former in
itself being GNU tar specific - libarchive tar does not allow xa.
While it makes little sense to use xaf with libarchive tar, that is
implementation detail which gets in the way when trying to write trivial
tooling/scripts.
For the sake of compatibility, reduce the error to a warning and augment
the message itself. Making it clear that the option makes little sense.
Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
Reference:https://github.com/libarchive/libarchive/commit/56c920eab3352f7877ee0cf9e472c1ab376c7e3e
Conflict:NA
---
tar/bsdtar.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/tar/bsdtar.c b/tar/bsdtar.c
index af41be5..f4f008b 100644
--- a/tar/bsdtar.c
+++ b/tar/bsdtar.c
@@ -796,8 +796,14 @@ main(int argc, char **argv)
"Must specify one of -c, -r, -t, -u, -x");
/* Check boolean options only permitted in certain modes. */
- if (bsdtar->flags & OPTFLAG_AUTO_COMPRESS)
- only_mode(bsdtar, "-a", "c");
+ if (bsdtar->flags & OPTFLAG_AUTO_COMPRESS) {
+ only_mode(bsdtar, "-a", "cx");
+ if (bsdtar->mode == 'x') {
+ bsdtar->flags &= ~OPTFLAG_AUTO_COMPRESS;
+ lafe_warnc(0,
+ "Ignoring option -a in mode -x");
+ }
+ }
if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS)
only_mode(bsdtar, "--one-file-system", "cru");
if (bsdtar->flags & OPTFLAG_FAST_READ)
--
2.27.0

View File

@ -0,0 +1,30 @@
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 35b494c..64522da 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -3909,7 +3909,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.23.0

View File

@ -0,0 +1,67 @@
From 17f4e83c0f0fc3bacf4b2bbacb01f987bb5aff5f Mon Sep 17 00:00:00 2001
From: Grzegorz Antoniak <ga@anadoxin.org>
Date: Fri, 12 Feb 2021 20:18:31 +0100
Subject: [PATCH] RAR5 reader: fix invalid memory access in some files
RAR5 reader uses several variables to manage the window buffer during
extraction: the buffer itself (`window_buf`), the current size of the
window buffer (`window_size`), and a helper variable (`window_mask`)
that is used to constrain read and write offsets to the window buffer.
Some specially crafted files can force the unpacker to update the
`window_mask` variable to a value that is out of sync with current
buffer size. If the `window_mask` will be bigger than the actual buffer
size, then an invalid access operation can happen (SIGSEGV).
This commit ensures that if the `window_size` and `window_mask` will be
changed, the window buffer will be reallocated to the proper size, so no
invalid memory operation should be possible.
This commit contains a test file from OSSFuzz #30442.
Reference:https://github.com/libarchive/libarchive/commit/17f4e83c0f0fc3bacf4b2bbacb01f987bb5aff5f
Conflict:NA
---
libarchive/archive_read_support_format_rar5.c | 27 ++++++++++++++-----
1 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c
index a91c73f8b..880ba6612 100644
--- a/libarchive/archive_read_support_format_rar5.c
+++ b/libarchive/archive_read_support_format_rar5.c
@@ -1772,14 +1772,29 @@ static int process_head_file(struct archive_read* a, struct rar5* rar,
}
}
- /* If we're currently switching volumes, ignore the new definition of
- * window_size. */
- if(rar->cstate.switch_multivolume == 0) {
- /* Values up to 64M should fit into ssize_t on every
- * architecture. */
- rar->cstate.window_size = (ssize_t) window_size;
+ if(rar->cstate.window_size < (ssize_t) window_size &&
+ rar->cstate.window_buf)
+ {
+ /* If window_buf has been allocated before, reallocate it, so
+ * that its size will match new window_size. */
+
+ uint8_t* new_window_buf =
+ realloc(rar->cstate.window_buf, window_size);
+
+ if(!new_window_buf) {
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
+ "Not enough memory when trying to realloc the window "
+ "buffer.");
+ return ARCHIVE_FATAL;
+ }
+
+ rar->cstate.window_buf = new_window_buf;
}
+ /* Values up to 64M should fit into ssize_t on every
+ * architecture. */
+ rar->cstate.window_size = (ssize_t) window_size;
+
if(rar->file.solid > 0 && rar->file.solid_window_size == 0) {
/* Solid files have to have the same window_size across
whole archive. Remember the window_size parameter

View File

@ -0,0 +1,198 @@
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 64522da..41ebdaa 100644
--- a/libarchive/archive_write_disk_posix.c
+++ b/libarchive/archive_write_disk_posix.c
@@ -2445,6 +2445,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,
@@ -2458,24 +2459,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,
@@ -2487,14 +2513,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)
@@ -2647,7 +2672,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 153cc3a..900fb81 100644
--- a/libarchive/test/test_write_disk_fixup.c
+++ b/libarchive/test/test_write_disk_fixup.c
@@ -44,26 +44,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));
@@ -72,6 +96,8 @@ DEFINE_TEST(test_write_disk_fixup)
assertEqualInt(ARCHIVE_OK, archive_write_free(ad));
/* Test the entries on disk. */
- assertIsSymlink("dir", "victim", 0);
- assertFileMode("victim", 0600);
+ assertIsSymlink("dir1", "dir", 0);
+ assertIsSymlink("dir2", "file", 0);
+ assertFileMode("dir", 0700);
+ assertFileMode("file", 0600);
}
--
2.23.0

View File

@ -0,0 +1,211 @@
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 41ebdaa..1a3bba3 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 {
static int la_opendirat(int, const char *);
static int la_mktemp(struct archive_write_disk *);
+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) {
#endif
}
+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)
{
@@ -810,6 +845,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;
}
@@ -820,6 +856,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)) {
@@ -853,6 +890,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));
}
@@ -865,6 +903,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,
@@ -879,6 +918,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. */
}
@@ -2446,7 +2486,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,
@@ -2473,32 +2513,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
@@ -2672,6 +2733,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);
}
@@ -3771,6 +3833,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.23.0

View File

@ -0,0 +1,199 @@
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] 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 aba41e5..ed4e7a7 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 3928f3d..31d2705 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 b0f5dfa..a63b64a 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.23.0

View File

@ -1,57 +0,0 @@
From a7ce8a6aa7b710986ab918761c8d2ff1b0e9f537 Mon Sep 17 00:00:00 2001
From: Samanta Navarro <ferivoz@riseup.net>
Date: Sat, 28 Aug 2021 11:58:00 +0000
Subject: [PATCH] Fix size_t cast in read_mac_metadata_blob
The size_t data type on 32 bit systems is smaller than int64_t. Check
the int64_t value before casting to size_t. If the value is too large
then stop operation instead of continuing operation with truncated
value.
---
libarchive/archive_read_support_format_tar.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c
index 96d8101..7290df0 100644
--- a/libarchive/archive_read_support_format_tar.c
+++ b/libarchive/archive_read_support_format_tar.c
@@ -1396,6 +1396,7 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
struct archive_entry *entry, const void *h, size_t *unconsumed)
{
int64_t size;
+ size_t msize;
const void *data;
const char *p, *name;
const wchar_t *wp, *wname;
@@ -1434,6 +1435,11 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
/* Read the body as a Mac OS metadata blob. */
size = archive_entry_size(entry);
+ msize = (size_t)size;
+ if (size < 0 || (uintmax_t)msize != (uintmax_t)size) {
+ *unconsumed = 0;
+ return (ARCHIVE_FATAL);
+ }
/*
* TODO: Look beyond the body here to peek at the next header.
@@ -1447,13 +1453,13 @@ read_mac_metadata_blob(struct archive_read *a, struct tar *tar,
* Q: Is the above idea really possible? Even
* when there are GNU or pax extension entries?
*/
- data = __archive_read_ahead(a, (size_t)size, NULL);
+ data = __archive_read_ahead(a, msize, NULL);
if (data == NULL) {
*unconsumed = 0;
return (ARCHIVE_FATAL);
}
- archive_entry_copy_mac_metadata(entry, data, (size_t)size);
- *unconsumed = (size_t)((size + 511) & ~ 511);
+ archive_entry_copy_mac_metadata(entry, data, msize);
+ *unconsumed = (msize + 511) & ~ 511;
tar_flush_unconsumed(a, unconsumed);
return (tar_read_header(a, tar, entry, unconsumed));
}
--
2.27.0

View File

@ -0,0 +1,28 @@
From cfaa28168a07ea4a53276b63068f94fce37d6aff Mon Sep 17 00:00:00 2001
From: Tim Kientzle <kientzle@acm.org>
Date: Thu, 24 Mar 2022 10:35:00 +0100
Subject: [PATCH] ZIP reader: fix possible out-of-bounds read in
zipx_lzma_alone_init()
Fixes #1672
Conflict:NA
Reference:https://github.com/libarchive/libarchive/commit/cfaa28168a07ea4a53276b63068f94fce37d6aff
---
libarchive/archive_read_support_format_zip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
index 38ada70b5..9d6c900b2 100644
--- a/libarchive/archive_read_support_format_zip.c
+++ b/libarchive/archive_read_support_format_zip.c
@@ -1667,7 +1667,7 @@ zipx_lzma_alone_init(struct archive_read *a, struct zip *zip)
*/
/* Read magic1,magic2,lzma_params from the ZIPX stream. */
- if((p = __archive_read_ahead(a, 9, NULL)) == NULL) {
+ if(zip->entry_bytes_remaining < 9 || (p = __archive_read_ahead(a, 9, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Truncated lzma data");
return (ARCHIVE_FATAL);

View File

@ -0,0 +1,38 @@
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)
Conflict:NA
Reference:https://github.com/libarchive/libarchive/commit/fd180c36036df7181a64931264732a10ad8cd024
---
libarchive/archive_write.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
index 66592e826..27626b541 100644
--- a/libarchive/archive_write.c
+++ b/libarchive/archive_write.c
@@ -201,6 +201,10 @@ __archive_write_allocate_filter(struct archive *_a)
struct archive_write_filter *f;
f = calloc(1, sizeof(*f));
+
+ if (f == NULL)
+ return (NULL);
+
f->archive = _a;
f->state = ARCHIVE_WRITE_FILTER_STATE_NEW;
if (a->filter_first == NULL)
@@ -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;

View 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
Reference:https://github.com/libarchive/libarchive/commit/eac15e252010c1189a5c0f461364dbe2cd2a68b1
Conflict:copy_from_lzss_window_to_unp() -> copy_from_lzss_window();adapt context
---
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 c2666b2..512f5a6 100644
--- a/libarchive/archive_read_support_format_rar.c
+++ b/libarchive/archive_read_support_format_rar.c
@@ -358,7 +358,7 @@ static int make_table_recurse(struct archive_read *, struct huffman_code *, int,
struct huffman_table_entry *, int, int);
static int64_t expand(struct archive_read *, int64_t);
static int copy_from_lzss_window(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 *);
/*
@@ -1936,7 +1936,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(a, buff, rar->offset, (int)bs);
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK)
return (ret);
rar->offset += bs;
@@ -2065,7 +2065,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(a, buff, rar->offset, (int)bs);
+ ret = copy_from_lzss_window(a, buff, rar->offset, bs);
if (ret != ARCHIVE_OK)
return (ret);
rar->offset += bs;
@@ -2923,11 +2923,16 @@ bad_data:
static int
copy_from_lzss_window(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)
@@ -2939,17 +2944,17 @@ copy_from_lzss_window(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],
@@ -2959,9 +2964,7 @@ copy_from_lzss_window(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)
@@ -2969,6 +2972,11 @@ copy_from_lzss_window(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 *

View File

@ -2,7 +2,7 @@
Name: libarchive
Version: 3.4.3
Release: 3
Release: 8
Summary: Multi-format archive and compression library
License: BSD
@ -12,6 +12,7 @@ Source0: https://www.libarchive.org/downloads/%{name}-%{version}.tar.gz
BuildRequires: gcc bison sharutils zlib-devel bzip2-devel xz-devel
BuildRequires: lzo-devel e2fsprogs-devel libacl-devel libattr-devel
BuildRequires: openssl-devel libxml2-devel lz4-devel automake libzstd-devel
BuildRequires: libtool
Provides: bsdtar bsdcpio bsdcat
Obsoletes: bsdtar bsdcpio bsdcat
@ -19,7 +20,16 @@ Obsoletes: bsdtar bsdcpio bsdcat
Patch6001: libarchive-uninitialized-value.patch
Patch6002: libarchive-3.4.3-lchmod-support-check.patch
Patch6003: libarchive-3.4.3-avoid-stack-overflow.patch
Patch6004: backport-CVE-2021-36976.patch
Patch6004: backport-0001-CVE-2021-36976.patch
Patch6005: backport-0002-CVE-2021-36976.patch
Patch6006: backport-CVE-2021-23177.patch
Patch6007: backport-0001-CVE-2021-31566.patch
Patch6008: backport-0002-CVE-2021-31566.patch
Patch6009: backport-0003-CVE-2021-31566.patch
Patch6010: backport-0004-CVE-2021-31566.patch
Patch6011: backport-CVE-2022-26280.patch
Patch6012: backport-CVE-2022-36227.patch
Patch6013: backport-CVE-2024-20696.patch
%description
%{name} is an open-source BSD-licensed C programming library that
@ -42,6 +52,7 @@ applications that want to make use of %{name}.
%autosetup -n %{name}-%{version} -p1
%build
autoreconf -ifv
%configure --disable-rpath
%disable_rpath
@ -150,6 +161,27 @@ run_testsuite
%{_mandir}/man5/*
%changelog
* Thu Jun 06 2024 lingsheng <lingsheng1@h-partners.com> - 3.4.3-8
- Type:CVE
- ID:CVE-2024-20696
- SUG:NA
- DESC:fix CVE-2024-20696
* Thu Mar 02 2023 zhangpan <zhangpan103@partners.com> - 3.4.3-7
- fix CVE-2021-36976 patch
* Fri Nov 25 2022 wangkeorng <wangkerong@partners.com> - 3.4.3-6
- fix CVE-2022-36227
* Mon Jul 04 2022 wangkeorng <wangkerong@partners.com> - 3.4.3-5
- fix CVE-2022-26280
* Wed Jan 12 2022 yangcheng <yangcheng87@huawei.com> - 3.4.3-4
- Type:CVE
- ID:CVE-2021-23177,CVE-2021-31566
- SUG:NA
- DESC:fix CVE-2021-23177,CVE-2021-31566
* Thu Oct 14 2021 yangcheng <yangcheng87@huawei.com> - 3.4.3-3
- Type:CVE
- ID:CVE-2021-36976