File 1565.patch of Package libarchive.39859

commit fba4f123cc456d2b2538f811bb831483bf336bad
Author: Martin Matuska <martin@matuska.org>
Date:   Sat Aug 21 20:51:07 2021 +0200

    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

Index: libarchive-3.3.3/libarchive/archive_disk_acl_freebsd.c
===================================================================
--- libarchive-3.3.3.orig/libarchive/archive_disk_acl_freebsd.c
+++ libarchive-3.3.3/libarchive/archive_disk_acl_freebsd.c
@@ -319,7 +319,7 @@ translate_acl(struct archive_read_disk *
 
 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
 		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
 	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 archi
 	    & 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 archi
 #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
Index: libarchive-3.3.3/libarchive/archive_disk_acl_linux.c
===================================================================
--- libarchive-3.3.3.orig/libarchive/archive_disk_acl_linux.c
+++ libarchive-3.3.3/libarchive/archive_disk_acl_linux.c
@@ -343,6 +343,11 @@ set_richacl(struct archive *a, int fd, c
 		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
 		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 archi
 	    & 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 */
Index: libarchive-3.3.3/libarchive/archive_disk_acl_sunos.c
===================================================================
--- libarchive-3.3.3.orig/libarchive/archive_disk_acl_sunos.c
+++ libarchive-3.3.3/libarchive/archive_disk_acl_sunos.c
@@ -445,7 +445,7 @@ translate_acl(struct archive_read_disk *
 
 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;
@@ -469,7 +469,6 @@ set_acl(struct archive *a, int fd, const
 	if (entries == 0)
 		return (ARCHIVE_OK);
 
-
 	switch (ae_requested_type) {
 	case ARCHIVE_ENTRY_ACL_TYPE_POSIX1E:
 		cmd = SETACL;
@@ -494,6 +493,12 @@ set_acl(struct archive *a, int fd, const
 		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,
@@ -803,7 +808,7 @@ archive_write_disk_set_acls(struct archi
 	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 */
@@ -812,7 +817,7 @@ archive_write_disk_set_acls(struct archi
 #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
openSUSE Build Service is sponsored by