aboutsummaryrefslogtreecommitdiff
path: root/contrib/libarchive
diff options
context:
space:
mode:
authorMartin Matuska <mm@FreeBSD.org>2018-11-26 11:04:35 +0000
committerMartin Matuska <mm@FreeBSD.org>2018-11-26 11:04:35 +0000
commit7d69e4cde77bd1e4caad686f04a543ac96fd25e3 (patch)
tree1b0036f93fb1335729a93217085c33296deed7e5 /contrib/libarchive
parent6bbd1d19fd353c10ca9343ed76df312381524bf7 (diff)
parent09d835e31de85341ea1a0bbd28f6c8062324d504 (diff)
downloadsrc-7d69e4cde77bd1e4caad686f04a543ac96fd25e3.tar.gz
src-7d69e4cde77bd1e4caad686f04a543ac96fd25e3.zip
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
Notes
Notes: svn path=/head/; revision=340939
Diffstat (limited to 'contrib/libarchive')
-rw-r--r--contrib/libarchive/libarchive/archive_acl.c51
-rw-r--r--contrib/libarchive/libarchive/archive_write_disk_posix.c27
-rw-r--r--contrib/libarchive/libarchive/test/test_extattr_freebsd.c46
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_rar5.c8
4 files changed, 78 insertions, 54 deletions
diff --git a/contrib/libarchive/libarchive/archive_acl.c b/contrib/libarchive/libarchive/archive_acl.c
index 6ce7ab66093a..512beee1f734 100644
--- a/contrib/libarchive/libarchive/archive_acl.c
+++ b/contrib/libarchive/libarchive/archive_acl.c
@@ -1585,17 +1585,29 @@ 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)++;
+ }
+
+ /* Handle in-field comments */
+ if (*sep == L'#') {
+ while (**wp != L'\0' && **wp != L',' && **wp != L'\n') {
+ (*wp)++;
+ }
+ *sep = **wp;
}
- (*end)++;
/* Adjust scanner location. */
if (**wp != L'\0')
@@ -1646,7 +1658,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
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')
diff --git a/contrib/libarchive/libarchive/archive_write_disk_posix.c b/contrib/libarchive/libarchive/archive_write_disk_posix.c
index d164a292b0c6..b6b220fbe6a7 100644
--- a/contrib/libarchive/libarchive/archive_write_disk_posix.c
+++ b/contrib/libarchive/libarchive/archive_write_disk_posix.c
@@ -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;
}
@@ -2223,6 +2239,15 @@ create_filesystem_object(struct archive_write_disk *a)
*/
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:
/* POSIX requires that we fall through here. */
diff --git a/contrib/libarchive/libarchive/test/test_extattr_freebsd.c b/contrib/libarchive/libarchive/test/test_extattr_freebsd.c
index f1fe53442262..ff05aa4a04b1 100644
--- a/contrib/libarchive/libarchive/test/test_extattr_freebsd.c
+++ b/contrib/libarchive/libarchive/test/test_extattr_freebsd.c
@@ -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
diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar5.c b/contrib/libarchive/libarchive/test/test_read_format_rar5.c
index 6c570f1c6643..0ccedc76f376 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_rar5.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_rar5.c
@@ -90,7 +90,7 @@ int verify_data(const uint8_t* data_ptr, int magic, int size) {
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_entry* ae, uint32_t crc) {
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;
}