Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 26 Nov 2018 11:04:35 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r340939 - in head/contrib/libarchive/libarchive: . test
Message-ID:  <201811261104.wAQB4ZLL015459@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Mon Nov 26 11:04:35 2018
New Revision: 340939
URL: https://svnweb.freebsd.org/changeset/base/340939

Log:
  MFV r340938:
  Sync libarchive with vendor.
  
  Relevant vendor changes:
    Issue #1096: Support extracting ACLs with in-entry comments (GNU tar)
    PR #1023: Support extracting extattrs as non-root on non-user-writeable
              files
  
  MFC after:	1 week

Modified:
  head/contrib/libarchive/libarchive/archive_acl.c
  head/contrib/libarchive/libarchive/archive_write_disk_posix.c
  head/contrib/libarchive/libarchive/test/test_extattr_freebsd.c
  head/contrib/libarchive/libarchive/test/test_read_format_rar5.c
Directory Properties:
  head/contrib/libarchive/   (props changed)

Modified: head/contrib/libarchive/libarchive/archive_acl.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_acl.c	Mon Nov 26 11:01:51 2018	(r340938)
+++ head/contrib/libarchive/libarchive/archive_acl.c	Mon Nov 26 11:04:35 2018	(r340939)
@@ -1585,18 +1585,30 @@ next_field_w(const wchar_t **wp, const wchar_t **start
 
 	/* Scan for the separator. */
 	while (**wp != L'\0' && **wp != L',' && **wp != L':' &&
-	    **wp != L'\n') {
+	    **wp != L'\n' && **wp != L'#') {
 		(*wp)++;
 	}
 	*sep = **wp;
 
-	/* Trim trailing whitespace to locate end of field. */
-	*end = *wp - 1;
-	while (**end == L' ' || **end == L'\t' || **end == L'\n') {
-		(*end)--;
+	/* Locate end of field, trim trailing whitespace if necessary */
+	if (*wp == *start) {
+		*end = *wp;
+	} else {
+		*end = *wp - 1;
+		while (**end == L' ' || **end == L'\t' || **end == L'\n') {
+			(*end)--;
+		}
+		(*end)++;
 	}
-	(*end)++;
 
+	/* Handle in-field comments */
+	if (*sep == L'#') {
+		while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
+			(*wp)++;
+		}
+		*sep = **wp;
+	}
+
 	/* Adjust scanner location. */
 	if (**wp != L'\0')
 		(*wp)++;
@@ -1646,7 +1658,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const
 	ret = ARCHIVE_OK;
 	types = 0;
 
-	while (text != NULL  &&  *text != '\0') {
+	while (text != NULL &&  *text != '\0') {
 		/*
 		 * Parse the fields out of the next entry,
 		 * advance 'text' to start of next entry.
@@ -2057,23 +2069,30 @@ next_field(const char **p, const char **start,
 	*start = *p;
 
 	/* Scan for the separator. */
-	while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n') {
+	while (**p != '\0' && **p != ',' && **p != ':' && **p != '\n' &&
+	    **p != '#') {
 		(*p)++;
 	}
 	*sep = **p;
 
-	/* If the field is only whitespace, bail out now. */
-	if (**p == '\0') {
+	/* Locate end of field, trim trailing whitespace if necessary */
+	if (*p == *start) {
 		*end = *p;
-		return;
+	} else {
+		*end = *p - 1;
+		while (**end == ' ' || **end == '\t' || **end == '\n') {
+			(*end)--;
+		}
+		(*end)++;
 	}
 
-	/* Trim trailing whitespace to locate end of field. */
-	*end = *p - 1;
-	while (**end == ' ' || **end == '\t' || **end == '\n') {
-		(*end)--;
+	/* Handle in-field comments */
+	if (*sep == '#') {
+		while (**p != '\0' && **p != ',' && **p != '\n') {
+			(*p)++;
+		}
+		*sep = **p;
 	}
-	(*end)++;
 
 	/* Adjust scanner location. */
 	if (**p != '\0')

Modified: head/contrib/libarchive/libarchive/archive_write_disk_posix.c
==============================================================================
--- head/contrib/libarchive/libarchive/archive_write_disk_posix.c	Mon Nov 26 11:01:51 2018	(r340938)
+++ head/contrib/libarchive/libarchive/archive_write_disk_posix.c	Mon Nov 26 11:04:35 2018	(r340939)
@@ -1705,6 +1705,20 @@ _archive_write_disk_finish_entry(struct archive *_a)
 	}
 
 	/*
+	 * HYPOTHESIS:
+	 * If we're not root, we won't be setting any security
+	 * attributes that may be wiped by the set_mode() routine
+	 * below.  We also can't set xattr on non-owner-writable files,
+	 * which may be the state after set_mode(). Perform
+	 * set_xattrs() first based on these constraints.
+	 */
+	if (a->user_uid != 0 &&
+	    (a->todo & TODO_XATTR)) {
+		int r2 = set_xattrs(a);
+		if (r2 < ret) ret = r2;
+	}
+
+	/*
 	 * set_mode must precede ACLs on systems such as Solaris and
 	 * FreeBSD where setting the mode implicitly clears extended ACLs
 	 */
@@ -1717,8 +1731,10 @@ _archive_write_disk_finish_entry(struct archive *_a)
 	 * Security-related extended attributes (such as
 	 * security.capability on Linux) have to be restored last,
 	 * since they're implicitly removed by other file changes.
+	 * We do this last only when root.
 	 */
-	if (a->todo & TODO_XATTR) {
+	if (a->user_uid == 0 &&
+	    (a->todo & TODO_XATTR)) {
 		int r2 = set_xattrs(a);
 		if (r2 < ret) ret = r2;
 	}
@@ -2222,6 +2238,15 @@ create_filesystem_object(struct archive_write_disk *a)
 	 * security, so we never restore them at this point.
 	 */
 	mode = final_mode & 0777 & ~a->user_umask;
+
+	/* 
+	 * Always create writable such that [f]setxattr() works if we're not
+	 * root.
+	 */
+	if (a->user_uid != 0 &&
+	    a->todo & (TODO_HFS_COMPRESSION | TODO_XATTR)) {
+		mode |= 0200;
+	}
 
 	switch (a->mode & AE_IFMT) {
 	default:

Modified: head/contrib/libarchive/libarchive/test/test_extattr_freebsd.c
==============================================================================
--- head/contrib/libarchive/libarchive/test/test_extattr_freebsd.c	Mon Nov 26 11:01:51 2018	(r340938)
+++ head/contrib/libarchive/libarchive/test/test_extattr_freebsd.c	Mon Nov 26 11:04:35 2018	(r340939)
@@ -49,7 +49,6 @@ DEFINE_TEST(test_extattr_freebsd)
 	struct archive_entry *ae;
 	ssize_t n;
 	int fd;
-	int extattr_privilege_bug = 0;
 
 	/*
 	 * First, do a quick manual set/read of an extended attribute
@@ -73,24 +72,6 @@ DEFINE_TEST(test_extattr_freebsd)
 	assertEqualInt(4, n);
 	close(fd);
 
-	/*
-	 * Repeat the above, but with file permissions set to 0000.
-	 * This should work (extattr_set_fd() should follow fd
-	 * permissions, not file permissions), but is known broken on
-	 * some versions of FreeBSD.
-	 */
-	fd = open("pretest2", O_RDWR | O_CREAT, 00000);
-	failure("Could not create test file?!");
-	if (!assert(fd >= 0))
-		return;
-
-	n = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, "testattr", "1234", 4);
-	if (n != 4) {
-		skipping("Restoring xattr to an unwritable file seems to be broken on this platform");
-		extattr_privilege_bug = 1;
-	}
-	close(fd);
-
 	/* Create a write-to-disk object. */
 	assert(NULL != (a = archive_write_disk_new()));
 	archive_write_disk_set_options(a,
@@ -120,16 +101,12 @@ DEFINE_TEST(test_extattr_freebsd)
 	archive_entry_free(ae);
 
 	/* Close the archive. */
-	if (extattr_privilege_bug)
-		/* If the bug is here, write_close will return warning. */
-		assertEqualIntA(a, ARCHIVE_WARN, archive_write_close(a));
-	else
-		assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
-	assertEqualInt(ARCHIVE_OK, archive_write_free(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
 
 	/* Verify the data on disk. */
 	assertEqualInt(0, stat("test0", &st));
 	assertEqualInt(st.st_mtime, 123456);
+	assertEqualInt(st.st_mode & 0777, 0755);
 	/* Verify extattr */
 	n = extattr_get_file("test0", EXTATTR_NAMESPACE_USER,
 	    "foo", buff, sizeof(buff));
@@ -141,17 +118,20 @@ DEFINE_TEST(test_extattr_freebsd)
 	/* Verify the data on disk. */
 	assertEqualInt(0, stat("test1", &st));
 	assertEqualInt(st.st_mtime, 12345678);
+	assertEqualInt(st.st_mode & 0777, 0);
+	/*
+	 * If we are not root, we have to make test1 user readable
+	 * or extattr_get_file() will fail
+	 */
+	if (geteuid() != 0) {
+		chmod("test1", S_IRUSR);
+	}
 	/* Verify extattr */
 	n = extattr_get_file("test1", EXTATTR_NAMESPACE_USER,
 	    "bar", buff, sizeof(buff));
-	if (extattr_privilege_bug) {
-		/* If we have the bug, the extattr won't have been written. */
-		assertEqualInt(n, -1);
-	} else {
-		if (assertEqualInt(n, 6)) {
-			buff[n] = '\0';
-			assertEqualString(buff, "123456");
-		}
+	if (assertEqualInt(n, 6)) {
+		buff[n] = '\0';
+		assertEqualString(buff, "123456");
 	}
 
 	/* Use libarchive APIs to read the file back into an entry and

Modified: head/contrib/libarchive/libarchive/test/test_read_format_rar5.c
==============================================================================
--- head/contrib/libarchive/libarchive/test/test_read_format_rar5.c	Mon Nov 26 11:01:51 2018	(r340938)
+++ head/contrib/libarchive/libarchive/test/test_read_format_rar5.c	Mon Nov 26 11:04:35 2018	(r340939)
@@ -90,7 +90,7 @@ int verify_data(const uint8_t* data_ptr, int magic, in
 
 static
 int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) {
-    la_ssize_t fsize, read;
+    la_ssize_t fsize, bytes_read;
     uint8_t* buf;
     int ret = 1;
     uint32_t computed_crc;
@@ -100,9 +100,9 @@ int extract_one(struct archive* a, struct archive_entr
     if(buf == NULL)
         return 1;
 
-    read = archive_read_data(a, buf, fsize);
-    if(read != fsize) {
-        assertEqualInt(read, fsize);
+    bytes_read = archive_read_data(a, buf, fsize);
+    if(bytes_read != fsize) {
+        assertEqualInt(bytes_read, fsize);
         goto fn_exit;
     }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811261104.wAQB4ZLL015459>