summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Matuška <martin@matuska.org>2018-11-25 10:13:08 +0100
committerGitHub <noreply@github.com>2018-11-25 10:13:08 +0100
commite90b2a0eccbcdf31c78c4bd472399043c0411a84 (patch)
treeb8b8a6d4999919a3269ef2289c3162bcb987401d
parent6f0bd4b3a50d073831fae27399591ee29d983f84 (diff)
parentd30a8faa42b36651194de4dc8dfebac99718db28 (diff)
downloadlibarchive-e90b2a0eccbcdf31c78c4bd472399043c0411a84.tar.gz
Merge pull request #1023 from eborisch/master
If extended attributes or HFS compression are to be extracted as non root, create files owner-writable first.
-rw-r--r--libarchive/archive_write_disk_posix.c27
1 files changed, 26 insertions, 1 deletions
diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c
index 3fd5f579..003e17d7 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. */