diff options
author | Martin Matuska <mm@FreeBSD.org> | 2018-11-26 11:01:51 +0000 |
---|---|---|
committer | Martin Matuska <mm@FreeBSD.org> | 2018-11-26 11:01:51 +0000 |
commit | 09d835e31de85341ea1a0bbd28f6c8062324d504 (patch) | |
tree | a6efa066317d7dc3e19934c8088b0315e65070fa | |
parent | fd2a102f7ba73f37fbac1c994086b23f438cbf13 (diff) | |
download | src-09d835e31de85341ea1a0bbd28f6c8062324d504.tar.gz src-09d835e31de85341ea1a0bbd28f6c8062324d504.zip |
Update vendor/libarchive/dist to git 2c5e9bdbb62eeb56a37776f796c15ed16727193e
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-writable files
Notes
Notes:
svn path=/vendor/libarchive/dist/; revision=340938
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | libarchive/archive_acl.c | 51 | ||||
-rw-r--r-- | libarchive/archive_write_disk_posix.c | 27 | ||||
-rw-r--r-- | libarchive/test/test_extattr_freebsd.c | 46 | ||||
-rw-r--r-- | libarchive/test/test_read_format_rar5.c | 8 |
5 files changed, 80 insertions, 54 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a5641ade2411..4d225b3201bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -592,6 +592,8 @@ ENDIF(ZSTD_FOUND) MARK_AS_ADVANCED(CLEAR ZSTD_INCLUDE_DIR) MARK_AS_ADVANCED(CLEAR ZSTD_LIBRARY) +set(CMAKE_REQUIRED_LIBRARIES) + # # Check headers # diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c index 6ce7ab66093a..512beee1f734 100644 --- a/libarchive/archive_acl.c +++ b/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/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index 3fd5f5798514..003e17d77367 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/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/libarchive/test/test_extattr_freebsd.c b/libarchive/test/test_extattr_freebsd.c index 8ffe756d1216..7cb30b56067a 100644 --- a/libarchive/test/test_extattr_freebsd.c +++ b/libarchive/test/test_extattr_freebsd.c @@ -48,7 +48,6 @@ DEFINE_TEST(test_extattr_freebsd) struct archive *a; struct archive_entry *ae; int n, fd; - int extattr_privilege_bug = 0; /* * First, do a quick manual set/read of an extended attribute @@ -72,24 +71,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, @@ -119,16 +100,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)); @@ -140,17 +117,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/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c index 6c570f1c6643..0ccedc76f376 100644 --- a/libarchive/test/test_read_format_rar5.c +++ b/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; } |