diff --git a/backport-CVE-2021-23177.patch b/backport-CVE-2021-23177.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6ccce55b115de4bed2470948200c45abf19bbd3 --- /dev/null +++ b/backport-CVE-2021-23177.patch @@ -0,0 +1,199 @@ +From fba4f123cc456d2b2538f811bb831483bf336bad Mon Sep 17 00:00:00 2001 +From: Martin Matuska +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 + diff --git a/libarchive.spec b/libarchive.spec index 85799a8b3aa9a71b4e895d54538cffb6be696422..9158a331a3df36334dd84d3bc3c9df5ed922fb55 100644 --- a/libarchive.spec +++ b/libarchive.spec @@ -2,7 +2,7 @@ Name: libarchive Version: 3.4.3 -Release: 2 +Release: 3 Summary: Multi-format archive and compression library License: BSD @@ -22,6 +22,7 @@ Patch6003: backport-0001-CVE-2021-31566.patch Patch6004: backport-0002-CVE-2021-31566.patch Patch6005: backport-0003-CVE-2021-31566.patch Patch6006: backport-0004-CVE-2021-31566.patch +Patch6007: backport-CVE-2021-23177.patch %description %{name} is an open-source BSD-licensed C programming library that @@ -153,6 +154,12 @@ run_testsuite %{_mandir}/man5/* %changelog +* Sat Feb 26 2022 songnannan - 3.4.3-3 +- Type:cve +- ID:CVE-2021-23177 +- SUG:NA +- DESC:fix cve-2021-23177 + * Sat Feb 26 2022 zhujunhao - 3.4.3-2 - Type:cve - ID:cve-2021-31566