svn commit: r315636 - in head: contrib/libarchive contrib/libarchive/cpio contrib/libarchive/libarchive contrib/libarchive/libarchive/test contrib/libarchive/tar contrib/libarchive/tar/test contrib...

Martin Matuska mm at FreeBSD.org
Mon Mar 20 13:02:30 UTC 2017


Author: mm
Date: Mon Mar 20 13:02:27 2017
New Revision: 315636
URL: https://svnweb.freebsd.org/changeset/base/315636

Log:
  MFV r315633, 315635:
  
  Sync libarchive with vendor
  
  Vendor changes/bugfixes (FreeBSD-related):
    PR 867 (bsdcpio): show numeric uid/gid when names are not found
    PR 870 (seekable zip): accept files with valid ZIP64 EOCD headers
    PR 880 (pax): Fix handling of "size" pax header keyword
    PR 887 (crypto): Discard 3072 bytes instead of 1024 of first keystream
    OSS-Fuzz issue 806 (mtree): rework mtree_atol10 integer parser
    Break ACL read/write code into platform-specific source files
    Unbreak static dependency on libbz2
  
  MFC after:	1 week

Added:
  head/contrib/libarchive/libarchive/archive_acl_maps.h
     - copied, changed from r315633, vendor/libarchive/dist/libarchive/archive_acl_maps.h
  head/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c
     - copied, changed from r315633, vendor/libarchive/dist/libarchive/archive_acl_maps_freebsd.c
  head/contrib/libarchive/libarchive/archive_platform_acl.h
     - copied unchanged from r315633, vendor/libarchive/dist/libarchive/archive_platform_acl.h
  head/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c
     - copied unchanged from r315633, vendor/libarchive/dist/libarchive/archive_read_disk_acl_freebsd.c
  head/contrib/libarchive/libarchive/archive_version_details.c
     - copied unchanged from r315633, vendor/libarchive/dist/libarchive/archive_version_details.c
  head/contrib/libarchive/libarchive/archive_write_disk_acl_freebsd.c
     - copied unchanged from r315633, vendor/libarchive/dist/libarchive/archive_write_disk_acl_freebsd.c
Deleted:
  head/contrib/libarchive/libarchive/archive_write_disk_acl.c
Modified:
  head/contrib/libarchive/NEWS
  head/contrib/libarchive/cpio/cpio.c
  head/contrib/libarchive/libarchive/archive_entry.3
  head/contrib/libarchive/libarchive/archive_entry_acl.3
  head/contrib/libarchive/libarchive/archive_platform.h
  head/contrib/libarchive/libarchive/archive_random.c
  head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
  head/contrib/libarchive/libarchive/archive_read_disk_private.h
  head/contrib/libarchive/libarchive/archive_read_open.3
  head/contrib/libarchive/libarchive/archive_read_support_format_mtree.c
  head/contrib/libarchive/libarchive/archive_read_support_format_tar.c
  head/contrib/libarchive/libarchive/archive_read_support_format_zip.c
  head/contrib/libarchive/libarchive/archive_util.c
  head/contrib/libarchive/libarchive/archive_write_disk_posix.c
  head/contrib/libarchive/libarchive/archive_write_disk_private.h
  head/contrib/libarchive/libarchive/test/test_acl_platform_nfs4.c
  head/contrib/libarchive/libarchive/test/test_acl_platform_posix1e.c
  head/contrib/libarchive/tar/bsdtar.1
  head/contrib/libarchive/tar/test/test_option_acls.c
  head/contrib/libarchive/test_utils/test_common.h
  head/contrib/libarchive/test_utils/test_main.c
  head/lib/libarchive/Makefile
  head/lib/libarchive/config_freebsd.h
  head/usr.bin/bsdcat/tests/Makefile
  head/usr.bin/cpio/tests/Makefile
  head/usr.bin/tar/tests/Makefile
Directory Properties:
  head/contrib/libarchive/   (props changed)

Modified: head/contrib/libarchive/NEWS
==============================================================================
--- head/contrib/libarchive/NEWS	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/NEWS	Mon Mar 20 13:02:27 2017	(r315636)
@@ -1,3 +1,5 @@
+Mar 16, 2017: NFSv4 ACL support for Linux (librichacl)
+
 Feb 26, 2017: libarchive 3.3.1 released
     Security & Feature release
 
@@ -293,7 +295,7 @@ May 04, 2008: libarchive 2.5.3b released
 	* libarchive: Mark which entry strings are set; be accurate about
 	  distinguishing empty strings ("") from unset ones (NULL)
 	* tar: Don't crash reading entries with empty filenames
-	* libarchive_test, bsdtar_test, bsdcpio_test:  Better detaults:
+	* libarchive_test, bsdtar_test, bsdcpio_test:  Better defaults:
 	  run all tests, delete temp dirs, summarize repeated failures
 	* -no-undefined to libtool for Cygwin
 	* libarchive_test: Skip large file tests on systems with 32-bit off_t

Modified: head/contrib/libarchive/cpio/cpio.c
==============================================================================
--- head/contrib/libarchive/cpio/cpio.c	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/cpio/cpio.c	Mon Mar 20 13:02:27 2017	(r315636)
@@ -1344,23 +1344,23 @@ lookup_name(struct cpio *cpio, struct na
 		cache->cache[slot].name = NULL;
 	}
 
-	if (lookup_fn(cpio, &name, id) == 0) {
-		if (name == NULL || name[0] == '\0') {
-			/* If lookup failed, format it as a number. */
-			snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
-			name = asnum;
-		}
-		cache->cache[slot].name = strdup(name);
-		if (cache->cache[slot].name != NULL) {
-			cache->cache[slot].id = id;
-			return (cache->cache[slot].name);
-		}
-		/*
-		 * Conveniently, NULL marks an empty slot, so
-		 * if the strdup() fails, we've just failed to
-		 * cache it.  No recovery necessary.
-		 */
-	}
+	if (lookup_fn(cpio, &name, id)) {
+		/* If lookup failed, format it as a number. */
+		snprintf(asnum, sizeof(asnum), "%u", (unsigned)id);
+		name = asnum;
+	}
+
+	cache->cache[slot].name = strdup(name);
+	if (cache->cache[slot].name != NULL) {
+		cache->cache[slot].id = id;
+		return (cache->cache[slot].name);
+	}
+
+	/*
+	 * Conveniently, NULL marks an empty slot, so
+	 * if the strdup() fails, we've just failed to
+	 * cache it.  No recovery necessary.
+	 */
 	return (NULL);
 }
 
@@ -1381,15 +1381,14 @@ lookup_uname_helper(struct cpio *cpio, c
 	errno = 0;
 	pwent = getpwuid((uid_t)id);
 	if (pwent == NULL) {
-		*name = NULL;
-		if (errno != 0 && errno != ENOENT)
+		if (errno && errno != ENOENT)
 			lafe_warnc(errno, "getpwuid(%s) failed",
 			    cpio_i64toa((int64_t)id));
-		return (errno);
+		return 1;
 	}
 
 	*name = pwent->pw_name;
-	return (0);
+	return 0;
 }
 
 static const char *
@@ -1409,15 +1408,14 @@ lookup_gname_helper(struct cpio *cpio, c
 	errno = 0;
 	grent = getgrgid((gid_t)id);
 	if (grent == NULL) {
-		*name = NULL;
-		if (errno != 0)
+		if (errno && errno != ENOENT)
 			lafe_warnc(errno, "getgrgid(%s) failed",
 			    cpio_i64toa((int64_t)id));
-		return (errno);
+		return 1;
 	}
 
 	*name = grent->gr_name;
-	return (0);
+	return 0;
 }
 
 /*

Copied and modified: head/contrib/libarchive/libarchive/archive_acl_maps.h (from r315633, vendor/libarchive/dist/libarchive/archive_acl_maps.h)
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_acl_maps.h	Mon Mar 20 11:12:31 2017	(r315633, copy source)
+++ head/contrib/libarchive/libarchive/archive_acl_maps.h	Mon Mar 20 13:02:27 2017	(r315636)
@@ -37,7 +37,6 @@ typedef struct {
 	const int p_perm;	/* Platform permission or flag */
 } acl_perm_map_t;
 
-#ifndef _ARCHIVE_ACL_MAPS_DEFS
 #if ARCHIVE_ACL_POSIX1E
 extern const acl_perm_map_t acl_posix_perm_map[];
 extern const int acl_posix_perm_map_size;
@@ -48,5 +47,4 @@ extern const int acl_nfs4_perm_map_size;
 extern const acl_perm_map_t acl_nfs4_flag_map[];
 extern const int acl_nfs4_flag_map_size;
 #endif
-#endif /* !_ARCHIVE_ACL_MAPS_DEFS */
 #endif /* ARCHIVE_ACL_MAPS_H_INCLUDED */

Copied and modified: head/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c (from r315633, vendor/libarchive/dist/libarchive/archive_acl_maps_freebsd.c)
==============================================================================
--- vendor/libarchive/dist/libarchive/archive_acl_maps_freebsd.c	Mon Mar 20 11:12:31 2017	(r315633, copy source)
+++ head/contrib/libarchive/libarchive/archive_acl_maps_freebsd.c	Mon Mar 20 13:02:27 2017	(r315636)
@@ -36,7 +36,6 @@
 #include "archive_entry.h"
 #include "archive_private.h"
 #include "archive_read_disk_private.h"
-#define _ARCHIVE_ACL_MAPS_DEFS
 #include "archive_acl_maps.h"
 
 const acl_perm_map_t acl_posix_perm_map[] = {

Modified: head/contrib/libarchive/libarchive/archive_entry.3
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry.3	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/libarchive/archive_entry.3	Mon Mar 20 13:02:27 2017	(r315636)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd Feburary 2, 2012
+.Dd February 2, 2012
 .Dt ARCHIVE_ENTRY 3
 .Os
 .Sh NAME

Modified: head/contrib/libarchive/libarchive/archive_entry_acl.3
==============================================================================
--- head/contrib/libarchive/libarchive/archive_entry_acl.3	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/libarchive/archive_entry_acl.3	Mon Mar 20 13:02:27 2017	(r315636)
@@ -267,7 +267,7 @@ Only inherit, do not apply the permissio
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT ( Sy n )
 Do not propagate inherit flags. Only first-level entries inherit ACLs.
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS ( Sy S )
-Trigger alarm or audit on succesful access.
+Trigger alarm or audit on successful access.
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS ( Sy F )
 Trigger alarm or audit on failed access.
 .It Dv ARCHIVE_ENTRY_ACL_ENTRY_INHERITED ( Sy I )
@@ -279,7 +279,7 @@ and
 .Fn archive_entry_acl_add_entry_w
 add a single ACL entry.
 For the access ACL and non-extended principals, the classic Unix permissions
-are updated. An archive enry cannot contain both POSIX.1e and NFSv4 ACL
+are updated. An archive entry cannot contain both POSIX.1e and NFSv4 ACL
 entries.
 .Pp
 .Fn archive_entry_acl_clear
@@ -303,7 +303,7 @@ for POSIX.1e ACLs and
 for NFSv4 ACLs. For POSIX.1e ACLs if
 .Dv ARCHIVE_ENTRY_ACL_TYPE_ACCESS
 is included and at least one extended ACL entry is found,
-the three non-extened ACLs are added.
+the three non-extended ACLs are added.
 .Pp
 .Fn archive_entry_acl_from_text
 and
@@ -367,7 +367,7 @@ and
 .Fn archive_entry_acl_to_text_w
 convert the ACL entries for the given type into a
 .Pq wide
-string of ACL entries separated by newline. If the the pointer
+string of ACL entries separated by newline. If the pointer
 .Fa len_p
 is not NULL, then the function shall return the length of the string
 .Pq not including the NULL terminator

Modified: head/contrib/libarchive/libarchive/archive_platform.h
==============================================================================
--- head/contrib/libarchive/libarchive/archive_platform.h	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/libarchive/archive_platform.h	Mon Mar 20 13:02:27 2017	(r315636)
@@ -143,40 +143,6 @@
 #endif
 
 /*
- * If this platform has <sys/acl.h>, acl_create(), acl_init(),
- * acl_set_file(), and ACL_USER, we assume it has the rest of the
- * POSIX.1e draft functions used in archive_read_extract.c.
- */
-#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
-#if HAVE_DECL_ACL_USER
-#define	HAVE_POSIX_ACL	1
-#elif HAVE_DECL_ACL_TYPE_EXTENDED && HAVE_MEMBERSHIP_H
-#define HAVE_DARWIN_ACL 1
-#endif
-#if HAVE_DECL_ACL_TYPE_NFS4
-#define	HAVE_FREEBSD_NFS4_ACL 1
-#endif
-#endif
-
-/*
- * If this platform has <sys/acl.h>, acl(), facl() and ACLENT_T
- * facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
- */
-#if HAVE_SYS_ACL_H && HAVE_ACL && HAVE_FACL && HAVE_ACLENT_T && \
-    HAVE_DECL_GETACL && HAVE_DECL_GETACLCNT && HAVE_DECL_SETACL
-#define	HAVE_SUN_ACL	1
-#if HAVE_ACE_T && HAVE_DECL_ACE_GETACL && HAVE_DECL_ACE_GETACLCNT && \
-    HAVE_DECL_ACE_SETACL
-#define HAVE_SUN_NFS4_ACL	1
-#endif
-#endif
-
-/* Define if platform supports NFSv4 ACLs */
-#if HAVE_FREEBSD_NFS4_ACL || HAVE_SUN_NFS4_ACL || HAVE_DARWIN_ACL
-#define HAVE_NFS4_ACL	1
-#endif
-
-/*
  * If we can't restore metadata using a file descriptor, then
  * for compatibility's sake, close files before trying to restore metadata.
  */

Copied: head/contrib/libarchive/libarchive/archive_platform_acl.h (from r315633, vendor/libarchive/dist/libarchive/archive_platform_acl.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/contrib/libarchive/libarchive/archive_platform_acl.h	Mon Mar 20 13:02:27 2017	(r315636, copy of r315633, vendor/libarchive/dist/libarchive/archive_platform_acl.h)
@@ -0,0 +1,49 @@
+/*-
+ * Copyright (c) 2017 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.
+ *
+ * $FreeBSD$
+ */
+
+/* !!ONLY FOR USE INTERNALLY TO LIBARCHIVE!! */
+
+#ifndef ARCHIVE_PLATFORM_ACL_H_INCLUDED
+#define ARCHIVE_PLATFORM_ACL_H_INCLUDED
+
+/*
+ * Determine what ACL types are supported
+ */
+#if ARCHIVE_ACL_FREEBSD || ARCHIVE_ACL_SUNOS || ARCHIVE_ACL_LIBACL
+#define ARCHIVE_ACL_POSIX1E     1
+#endif
+
+#if ARCHIVE_ACL_FREEBSD_NFS4 || ARCHIVE_ACL_SUNOS_NFS4 || \
+    ARCHIVE_ACL_DARWIN  || ARCHIVE_ACL_LIBRICHACL
+#define ARCHIVE_ACL_NFS4        1
+#endif
+
+#if ARCHIVE_ACL_POSIX1E || ARCHIVE_ACL_NFS4
+#define ARCHIVE_ACL_SUPPORT     1
+#endif
+
+#endif	/* ARCHIVE_PLATFORM_ACL_H_INCLUDED */

Modified: head/contrib/libarchive/libarchive/archive_random.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_random.c	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/libarchive/archive_random.c	Mon Mar 20 13:02:27 2017	(r315636)
@@ -221,8 +221,11 @@ arc4_stir(void)
 	/*
 	 * Discard early keystream, as per recommendations in:
 	 * "(Not So) Random Shuffles of RC4" by Ilya Mironov.
+	 * As per the Network Operations Division, cryptographic requirements
+	 * published on wikileaks on March 2017.
 	 */
-	for (i = 0; i < 1024; i++)
+
+	for (i = 0; i < 3072; i++)
 		(void)arc4_getbyte();
 	arc4_count = 1600000;
 }

Copied: head/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c (from r315633, vendor/libarchive/dist/libarchive/archive_read_disk_acl_freebsd.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/contrib/libarchive/libarchive/archive_read_disk_acl_freebsd.c	Mon Mar 20 13:02:27 2017	(r315636, copy of r315633, vendor/libarchive/dist/libarchive/archive_read_disk_acl_freebsd.c)
@@ -0,0 +1,371 @@
+/*-
+ * Copyright (c) 2003-2009 Tim Kientzle
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
+ * Copyright (c) 2016-2017 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 "archive_platform.h"
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ACL_H
+#define _ACL_PRIVATE /* For debugging */
+#include <sys/acl.h>
+#endif
+
+#include "archive_entry.h"
+#include "archive_private.h"
+#include "archive_read_disk_private.h"
+#include "archive_acl_maps.h"
+
+/*
+ * Translate FreeBSD ACLs into libarchive internal structure
+ */
+static int
+translate_acl(struct archive_read_disk *a,
+    struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
+{
+#if ARCHIVE_ACL_FREEBSD_NFS4
+	int brand;
+	acl_flagset_t	 acl_flagset;
+#endif
+	acl_tag_t	 acl_tag;
+	acl_entry_t	 acl_entry;
+	acl_permset_t	 acl_permset;
+	acl_entry_type_t acl_type;
+	int		 i, entry_acl_type, perm_map_size;
+	const acl_perm_map_t	*perm_map;
+	int		 r, s, ae_id, ae_tag, ae_perm;
+	void		*q;
+	const char	*ae_name;
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+	// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
+	// Make sure the "brand" on this ACL is consistent
+	// with the default_entry_acl_type bits provided.
+	if (acl_get_brand_np(acl, &brand) != 0) {
+		archive_set_error(&a->archive, errno,
+		    "Failed to read ACL brand");
+		return (ARCHIVE_WARN);
+	}
+	switch (brand) {
+	case ACL_BRAND_POSIX:
+		switch (default_entry_acl_type) {
+		case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
+		case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
+			break;
+		default:
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Invalid ACL entry type for POSIX.1e ACL");
+			return (ARCHIVE_WARN);
+		}
+		break;
+	case ACL_BRAND_NFS4:
+		if (default_entry_acl_type & ~ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+			    "Invalid ACL entry type for NFSv4 ACL");
+			return (ARCHIVE_WARN);
+		}
+		break;
+	default:
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		    "Unknown ACL brand");
+		return (ARCHIVE_WARN);
+	}
+#endif
+
+	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
+	if (s == -1) {
+		archive_set_error(&a->archive, errno,
+		    "Failed to get first ACL entry");
+		return (ARCHIVE_WARN);
+	}
+
+	while (s == 1) {
+		ae_id = -1;
+		ae_name = NULL;
+		ae_perm = 0;
+
+		if (acl_get_tag_type(acl_entry, &acl_tag) != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Failed to get ACL tag type");
+			return (ARCHIVE_WARN);
+		}
+		switch (acl_tag) {
+		case ACL_USER:
+			q = acl_get_qualifier(acl_entry);
+			if (q != NULL) {
+				ae_id = (int)*(uid_t *)q;
+				acl_free(q);
+				ae_name = archive_read_disk_uname(&a->archive,
+				    ae_id);
+			}
+			ae_tag = ARCHIVE_ENTRY_ACL_USER;
+			break;
+		case ACL_GROUP:
+			q = acl_get_qualifier(acl_entry);
+			if (q != NULL) {
+				ae_id = (int)*(gid_t *)q;
+				acl_free(q);
+				ae_name = archive_read_disk_gname(&a->archive,
+				    ae_id);
+			}
+			ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
+			break;
+		case ACL_MASK:
+			ae_tag = ARCHIVE_ENTRY_ACL_MASK;
+			break;
+		case ACL_USER_OBJ:
+			ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
+			break;
+		case ACL_GROUP_OBJ:
+			ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
+			break;
+		case ACL_OTHER:
+			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
+			break;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+		case ACL_EVERYONE:
+			ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
+			break;
+#endif
+		default:
+			/* Skip types that libarchive can't support. */
+			s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+			continue;
+		}
+
+		// XXX acl_type maps to allow/deny/audit/YYYY bits
+		entry_acl_type = default_entry_acl_type;
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+		if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+			/*
+			 * acl_get_entry_type_np() fails with non-NFSv4 ACLs
+			 */
+			if (acl_get_entry_type_np(acl_entry, &acl_type) != 0) {
+				archive_set_error(&a->archive, errno, "Failed "
+				    "to get ACL type from a NFSv4 ACL entry");
+				return (ARCHIVE_WARN);
+			}
+			switch (acl_type) {
+			case ACL_ENTRY_TYPE_ALLOW:
+				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
+				break;
+			case ACL_ENTRY_TYPE_DENY:
+				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
+				break;
+			case ACL_ENTRY_TYPE_AUDIT:
+				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_AUDIT;
+				break;
+			case ACL_ENTRY_TYPE_ALARM:
+				entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
+				break;
+			default:
+				archive_set_error(&a->archive, errno,
+				    "Invalid NFSv4 ACL entry type");
+				return (ARCHIVE_WARN);
+			}
+
+			/*
+			 * Libarchive stores "flag" (NFSv4 inheritance bits)
+			 * in the ae_perm bitmap.
+			 *
+			 * acl_get_flagset_np() fails with non-NFSv4 ACLs
+			 */
+			if (acl_get_flagset_np(acl_entry, &acl_flagset) != 0) {
+				archive_set_error(&a->archive, errno,
+				    "Failed to get flagset from a NFSv4 "
+				    "ACL entry");
+				return (ARCHIVE_WARN);
+			}
+			for (i = 0; i < acl_nfs4_flag_map_size; ++i) {
+				r = acl_get_flag_np(acl_flagset,
+				    acl_nfs4_flag_map[i].p_perm);
+				if (r == -1) {
+					archive_set_error(&a->archive, errno,
+					    "Failed to check flag in a NFSv4 "
+					    "ACL flagset");
+					return (ARCHIVE_WARN);
+				} else if (r)
+					ae_perm |= acl_nfs4_flag_map[i].a_perm;
+			}
+		}
+#endif
+
+		if (acl_get_permset(acl_entry, &acl_permset) != 0) {
+			archive_set_error(&a->archive, errno,
+			    "Failed to get ACL permission set");
+			return (ARCHIVE_WARN);
+		}
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+		if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
+			perm_map_size = acl_nfs4_perm_map_size;
+			perm_map = acl_nfs4_perm_map;
+		} else {
+#endif
+			perm_map_size = acl_posix_perm_map_size;
+			perm_map = acl_posix_perm_map;
+#if ARCHIVE_ACL_FREEBSD_NFS4
+		}
+#endif
+
+		for (i = 0; i < perm_map_size; ++i) {
+			r = acl_get_perm_np(acl_permset, perm_map[i].p_perm);
+			if (r == -1) {
+				archive_set_error(&a->archive, errno,
+				    "Failed to check permission in an ACL "
+				    "permission set");
+				return (ARCHIVE_WARN);
+			} else if (r)
+				ae_perm |= perm_map[i].a_perm;
+		}
+
+		archive_entry_acl_add_entry(entry, entry_acl_type,
+					    ae_perm, ae_tag,
+					    ae_id, ae_name);
+
+		s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
+		if (s == -1) {
+			archive_set_error(&a->archive, errno,
+			    "Failed to get next ACL entry");
+			return (ARCHIVE_WARN);
+		}
+	}
+	return (ARCHIVE_OK);
+}
+
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+    struct archive_entry *entry, int *fd)
+{
+	const char	*accpath;
+	acl_t		acl;
+	int		r;
+
+	accpath = NULL;
+
+	if (*fd < 0) {
+		accpath = archive_read_disk_entry_setup_path(a, entry, fd);
+		if (accpath == NULL)
+			return (ARCHIVE_WARN);
+	}
+
+	archive_entry_acl_clear(entry);
+
+	acl = NULL;
+
+#if ARCHIVE_ACL_FREEBSD_NFS4
+	/* Try NFSv4 ACL first. */
+	if (*fd >= 0)
+		acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
+	else if (!a->follow_symlinks)
+		acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
+	else
+		acl = acl_get_file(accpath, ACL_TYPE_NFS4);
+
+	/* Ignore "trivial" ACLs that just mirror the file mode. */
+	if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
+		acl_free(acl);
+		acl = NULL;
+		return (ARCHIVE_OK);
+	}
+
+	if (acl != NULL) {
+		r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
+		acl_free(acl);
+		acl = NULL;
+
+		if (r != ARCHIVE_OK) {
+			archive_set_error(&a->archive, errno,
+			    "Couldn't translate NFSv4 ACLs");
+		}
+
+		return (r);
+	}
+#endif
+
+	/* Retrieve access ACL from file. */
+	if (*fd >= 0)
+		acl = acl_get_fd_np(*fd, ACL_TYPE_ACCESS);
+#if HAVE_ACL_GET_LINK_NP
+	else if (!a->follow_symlinks)
+		acl = acl_get_link_np(accpath, ACL_TYPE_ACCESS);
+#else
+	else if ((!a->follow_symlinks)
+	    && (archive_entry_filetype(entry) == AE_IFLNK))
+		/* We can't get the ACL of a symlink, so we assume it can't
+		   have one. */
+		acl = NULL;
+#endif
+	else
+		acl = acl_get_file(accpath, ACL_TYPE_ACCESS);
+
+#if HAVE_ACL_IS_TRIVIAL_NP
+	/* Ignore "trivial" ACLs that just mirror the file mode. */
+	if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
+		acl_free(acl);
+		acl = NULL;
+	}
+#endif
+
+	if (acl != NULL) {
+		r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
+		acl_free(acl);
+		acl = NULL;
+
+		if (r != ARCHIVE_OK) {
+			archive_set_error(&a->archive, errno,
+			    "Couldn't translate access ACLs");
+			return (r);
+		}
+	}
+
+	/* Only directories can have default ACLs. */
+	if (S_ISDIR(archive_entry_mode(entry))) {
+		if (*fd >= 0)
+			acl = acl_get_fd_np(*fd, ACL_TYPE_DEFAULT);
+		else
+			acl = acl_get_file(accpath, ACL_TYPE_DEFAULT);
+		if (acl != NULL) {
+			r = translate_acl(a, entry, acl,
+			    ARCHIVE_ENTRY_ACL_TYPE_DEFAULT);
+			acl_free(acl);
+			if (r != ARCHIVE_OK) {
+				archive_set_error(&a->archive, errno,
+				    "Couldn't translate default ACLs");
+				return (r);
+			}
+		}
+	}
+	return (ARCHIVE_OK);
+}

Modified: head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c	Mon Mar 20 11:55:03 2017	(r315635)
+++ head/contrib/libarchive/libarchive/archive_read_disk_entry_from_file.c	Mon Mar 20 13:02:27 2017	(r315636)
@@ -26,23 +26,14 @@
  */
 
 #include "archive_platform.h"
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD");
 
 /* This is the tree-walking code for POSIX systems. */
 #if !defined(_WIN32) || defined(__CYGWIN__)
 
 #ifdef HAVE_SYS_TYPES_H
-/* Mac OSX requires sys/types.h before sys/acl.h. */
 #include <sys/types.h>
 #endif
-#ifdef HAVE_SYS_ACL_H
-#include <sys/acl.h>
-#endif
-#ifdef HAVE_DARWIN_ACL
-#include <membership.h>
-#include <grp.h>
-#include <pwd.h>
-#endif
 #ifdef HAVE_SYS_EXTATTR_H
 #include <sys/extattr.h>
 #endif
@@ -63,9 +54,6 @@ __FBSDID("$FreeBSD$");
 #ifdef HAVE_SYS_EA_H
 #include <sys/ea.h>
 #endif
-#ifdef HAVE_ACL_LIBACL_H
-#include <acl/libacl.h>
-#endif
 #ifdef HAVE_COPYFILE_H
 #include <copyfile.h>
 #endif
@@ -113,25 +101,6 @@ __FBSDID("$FreeBSD$");
 #define O_CLOEXEC	0
 #endif
 
-/*
- * Linux and FreeBSD plug this obvious hole in POSIX.1e in
- * different ways.
- */
-#if HAVE_ACL_GET_PERM
-#define	ACL_GET_PERM acl_get_perm
-#elif HAVE_ACL_GET_PERM_NP
-#define	ACL_GET_PERM acl_get_perm_np
-#endif
-
-/* NFSv4 platform ACL type */
-#if HAVE_DARWIN_ACL
-#define	ARCHIVE_PLATFORM_ACL_TYPE_NFS4	ACL_TYPE_EXTENDED
-#elif HAVE_FREEBSD_NFS4_ACL
-#define	ARCHIVE_PLATFORM_ACL_TYPE_NFS4	ACL_TYPE_NFS4
-#endif
-
-static int setup_acls(struct archive_read_disk *,
-    struct archive_entry *, int *fd);
 static int setup_mac_metadata(struct archive_read_disk *,
     struct archive_entry *, int *fd);
 static int setup_xattrs(struct archive_read_disk *,
@@ -143,6 +112,45 @@ static int setup_sparse_fiemap(struct ar
     struct archive_entry *, int *fd);
 #endif
 
+#if !ARCHIVE_ACL_SUPPORT
+int
+archive_read_disk_entry_setup_acls(struct archive_read_disk *a,
+    struct archive_entry *entry, int *fd)
+{
+	(void)a;      /* UNUSED */
+	(void)entry;  /* UNUSED */
+	(void)fd;     /* UNUSED */
+	return (ARCHIVE_OK);
+}
+#endif
+
+/*
+ * Enter working directory and return working pathname of archive_entry.
+ * If a pointer to an integer is provided and its value is below zero
+ * open a file descriptor on this pahtname.
+ */
+const char *
+archive_read_disk_entry_setup_path(struct archive_read_disk *a,
+    struct archive_entry *entry, int *fd)
+{
+	const char *path;
+
+	path = archive_entry_sourcepath(entry);
+
+	if (path == NULL || (a->tree != NULL &&
+	    a->tree_enter_working_dir(a->tree) != 0))
+		path = archive_entry_pathname(entry);
+	if (path == NULL) {
+		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+		   "Couldn't determine path");
+	} else if (fd != NULL && *fd < 0 && a->tree != NULL &&
+	    (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) {
+		*fd = a->open_on_current_dir(a->tree, path,
+		    O_RDONLY | O_NONBLOCK);
+	}
+	return (path);
+}
+
 int
 archive_read_disk_entry_from_file(struct archive *_a,
     struct archive_entry *entry,
@@ -277,7 +285,7 @@ archive_read_disk_entry_from_file(struct
 
 	r = 0;
 	if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0)
-		r = setup_acls(a, entry, &fd);
+		r = archive_read_disk_entry_setup_acls(a, entry, &fd);
 	if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) {
 		r1 = setup_xattrs(a, entry, &fd);
 		if (r1 < r)
@@ -326,19 +334,10 @@ setup_mac_metadata(struct archive_read_d
 	struct archive_string tempfile;
 
 	(void)fd; /* UNUSED */
-	name = archive_entry_sourcepath(entry);
+
+	name = archive_read_disk_entry_setup_path(a, entry, NULL);
 	if (name == NULL)
-		name = archive_entry_pathname(entry);
-	else if (a->tree != NULL && a->tree_enter_working_dir(a->tree) != 0) {
-		archive_set_error(&a->archive, errno,
-			    "Can't change dir to read extended attributes");
-			return (ARCHIVE_FAILED);
-	}
-	if (name == NULL) {
-		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-		    "Can't open file to read extended attributes: No name");
 		return (ARCHIVE_WARN);
-	}
 
 	/* Short-circuit if there's nothing to do. */
 	have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
@@ -424,1116 +423,6 @@ setup_mac_metadata(struct archive_read_d
 }
 #endif
 
-#if HAVE_DARWIN_ACL
-static int translate_guid(struct archive *, acl_entry_t,
-    int *, int *, const char **);
-
-static void add_trivial_nfs4_acl(struct archive_entry *);
-#endif
-
-#if HAVE_SUN_ACL
-static int
-sun_acl_is_trivial(void *, int, mode_t, int, int, int *);
-
-static void *
-sunacl_get(int cmd, int *aclcnt, int fd, const char *path)
-{
-	int cnt, cntcmd;
-	size_t size;
-	void *aclp;
-
-	if (cmd == GETACL) {
-		cntcmd = GETACLCNT;
-		size = sizeof(aclent_t);
-	}
-#if HAVE_SUN_NFS4_ACL
-	else if (cmd == ACE_GETACL) {
-		cntcmd = ACE_GETACLCNT;
-		size = sizeof(ace_t);
-	}
-#endif
-	else {
-		errno = EINVAL;
-		*aclcnt = -1;
-		return (NULL);
-	}
-
-	aclp = NULL;
-	cnt = -2;
-
-	while (cnt == -2 || (cnt == -1 && errno == ENOSPC)) {
-		if (path != NULL)
-			cnt = acl(path, cntcmd, 0, NULL);
-		else
-			cnt = facl(fd, cntcmd, 0, NULL);
-
-		if (cnt > 0) {
-			if (aclp == NULL)
-				aclp = malloc(cnt * size);
-			else
-				aclp = realloc(NULL, cnt * size);
-			if (aclp != NULL) {
-				if (path != NULL)
-					cnt = acl(path, cmd, cnt, aclp);
-				else
-					cnt = facl(fd, cmd, cnt, aclp);
-			}
-		} else {
-			if (aclp != NULL) {
-				free(aclp);
-				aclp = NULL;
-			}
-			break;
-		}
-	}
-
-	*aclcnt = cnt;
-	return (aclp);
-}
-#endif	/* HAVE_SUN_ACL */
-
-#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
-static int translate_acl(struct archive_read_disk *a,
-    struct archive_entry *entry,
-#if HAVE_SUN_ACL
-    void *aclp,
-    int aclcnt,
-#else
-    acl_t acl,
-#endif
-    int archive_entry_acl_type);
-
-static int
-setup_acls(struct archive_read_disk *a,
-    struct archive_entry *entry, int *fd)
-{
-	const char	*accpath;
-#if HAVE_SUN_ACL
-	void		*aclp;
-	int		aclcnt;
-#else
-	acl_t		acl;
-#endif
-	int		r;
-
-	accpath = NULL;
-
-#if HAVE_SUN_ACL || HAVE_DARWIN_ACL || HAVE_ACL_GET_FD_NP
-	if (*fd < 0)
-#else
-	/* For default ACLs on Linux we need reachable accpath */
-	if (*fd < 0 || S_ISDIR(archive_entry_mode(entry)))
-#endif
-	{
-		accpath = archive_entry_sourcepath(entry);
-		if (accpath == NULL || (a->tree != NULL &&
-		    a->tree_enter_working_dir(a->tree) != 0))
-			accpath = archive_entry_pathname(entry);
-		if (accpath == NULL) {
-			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
-			    "Couldn't determine file path to read ACLs");
-			return (ARCHIVE_WARN);
-		}
-		if (a->tree != NULL &&
-#if !HAVE_SUN_ACL && !HAVE_DARWIN_ACL && !HAVE_ACL_GET_FD_NP
-		    *fd < 0 &&
-#endif
-		    (a->follow_symlinks ||
-		    archive_entry_filetype(entry) != AE_IFLNK)) {
-			*fd = a->open_on_current_dir(a->tree,
-			    accpath, O_RDONLY | O_NONBLOCK);
-		}
-	}
-
-	archive_entry_acl_clear(entry);
-
-#if HAVE_SUN_ACL
-	aclp = NULL;
-#else
-	acl = NULL;
-#endif
-
-#if HAVE_NFS4_ACL
-	/* Try NFSv4 ACL first. */
-	if (*fd >= 0)
-#if HAVE_SUN_ACL
-		aclp = sunacl_get(ACE_GETACL, &aclcnt, *fd, NULL);
-#elif HAVE_ACL_GET_FD_NP
-		acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
-#else
-		acl = acl_get_fd(*fd);
-#endif
-#if HAVE_ACL_GET_LINK_NP
-	else if (!a->follow_symlinks)
-		acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
-#else
-	else if ((!a->follow_symlinks)
-	    && (archive_entry_filetype(entry) == AE_IFLNK))
-		/* We can't get the ACL of a symlink, so we assume it can't
-		   have one. */
-#if HAVE_SUN_ACL
-		aclp = NULL;
-#else
-		acl = NULL;
-#endif
-#endif /* !HAVE_ACL_GET_LINK_NP */
-	else
-#if HAVE_SUN_ACL
-		/* Solaris reads both POSIX.1e and NFSv4 ACLs here */
-		aclp = sunacl_get(ACE_GETACL, &aclcnt, 0, accpath);
-#else
-		acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
-#endif
-
-
-	/* Ignore "trivial" ACLs that just mirror the file mode. */
-#if HAVE_SUN_ACL
-	if (aclp != NULL && sun_acl_is_trivial(aclp, aclcnt,
-	    archive_entry_mode(entry), 1, S_ISDIR(archive_entry_mode(entry)),
-	    &r) == 0 && r == 1) {
-		free(aclp);
-		aclp = NULL;
-		return (ARCHIVE_OK);
-	}
-#elif HAVE_ACL_IS_TRIVIAL_NP
-	if (acl != NULL && acl_is_trivial_np(acl, &r) == 0 && r == 1) {
-		acl_free(acl);
-		acl = NULL;
-		return (ARCHIVE_OK);
-	}
-#endif
-
-#if HAVE_SUN_ACL
-	if (aclp != NULL)
-#else
-	if (acl != NULL)
-#endif
-	{
-		r = translate_acl(a, entry,
-#if HAVE_SUN_ACL
-		    aclp, aclcnt,
-#else
-		    acl,
-#endif
-		    ARCHIVE_ENTRY_ACL_TYPE_NFS4);
-#if HAVE_SUN_ACL
-		free(aclp);
-		aclp = NULL;
-#else
-		acl_free(acl);
-		acl = NULL;
-#endif

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list