]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
disk read: rework handling of paths for acls, xattrs and mac_metadata
authorMartin Matuska <martin@matuska.org>
Sat, 18 Feb 2017 01:36:20 +0000 (02:36 +0100)
committerMartin Matuska <martin@matuska.org>
Sat, 18 Feb 2017 01:36:20 +0000 (02:36 +0100)
If path is read from archive_entry_sourcepath(), always enter tree
working dir. If path is read from archive_entry_pathname(), don't.
This prevents reading acls, xattrs or mac_metadata from wrong files
or not at all if no fd is provided (e.g. default ACLs on Linux can
be read only from a pathname).

Fixes #501

libarchive/archive_read_disk_entry_from_file.c

index b9cd8da9017f162ae56549552500181cd54fd4ff..e81c28e57323fd5b0aa295ba814ad50f3f26f6d2 100644 (file)
@@ -321,20 +321,17 @@ setup_mac_metadata(struct archive_read_disk *a,
        name = archive_entry_sourcepath(entry);
        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);
        }
 
-       if (a->tree != NULL) {
-               if (a->tree_enter_working_dir(a->tree) != 0) {
-                       archive_set_error(&a->archive, errno,
-                                   "Couldn't change dir");
-                               return (ARCHIVE_FAILED);
-               }
-       }
-
        /* Short-circuit if there's nothing to do. */
        have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK);
        if (have_attrs == -1) {
@@ -456,19 +453,20 @@ setup_acls(struct archive_read_disk *a,
        accpath = archive_entry_sourcepath(entry);
        if (accpath == NULL)
                accpath = archive_entry_pathname(entry);
-
-       if (*fd < 0 && a->tree != NULL) {
-               if (a->follow_symlinks ||
-                   archive_entry_filetype(entry) != AE_IFLNK)
-                       *fd = a->open_on_current_dir(a->tree,
-                           accpath, O_RDONLY | O_NONBLOCK);
-               if (*fd < 0) {
-                       if (a->tree_enter_working_dir(a->tree) != 0) {
-                               archive_set_error(&a->archive, errno,
-                                   "Couldn't access %s", accpath);
-                               return (ARCHIVE_FAILED);
-                       }
-               }
+       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 ACLs");
+               return (ARCHIVE_WARN);
+       }
+       if (*fd < 0 && a->tree != NULL && (a->follow_symlinks ||
+           archive_entry_filetype(entry) != AE_IFLNK)) {
+               *fd = a->open_on_current_dir(a->tree,
+                   accpath, O_RDONLY | O_NONBLOCK);
+       }
+       if (*fd < 0 && accpath == NULL) {
+               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                   "Can't open file to read ACLs");
+               return (ARCHIVE_WARN);
        }
 
        archive_entry_acl_clear(entry);
@@ -1487,19 +1485,20 @@ setup_xattrs(struct archive_read_disk *a,
        path = archive_entry_sourcepath(entry);
        if (path == NULL)
                path = archive_entry_pathname(entry);
-
-       if (*fd < 0 && a->tree != NULL) {
-               if (a->follow_symlinks ||
-                   archive_entry_filetype(entry) != AE_IFLNK)
-                       *fd = a->open_on_current_dir(a->tree, path,
-                               O_RDONLY | O_NONBLOCK);
-               if (*fd < 0) {
-                       if (a->tree_enter_working_dir(a->tree) != 0) {
-                               archive_set_error(&a->archive, errno,
-                                   "Couldn't access %s", path);
-                               return (ARCHIVE_FAILED);
-                       }
-               }
+       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_WARN);
+       }
+       if (*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);
+       }
+       if (*fd < 0 && path == NULL) {
+               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                   "Can't open file to read extended attributes");
+               return (ARCHIVE_WARN);
        }
 
 #if HAVE_FLISTXATTR
@@ -1647,19 +1646,20 @@ setup_xattrs(struct archive_read_disk *a,
        path = archive_entry_sourcepath(entry);
        if (path == NULL)
                path = archive_entry_pathname(entry);
-
-       if (*fd < 0 && a->tree != NULL) {
-               if (a->follow_symlinks ||
-                   archive_entry_filetype(entry) != AE_IFLNK)
-                       *fd = a->open_on_current_dir(a->tree, path,
-                               O_RDONLY | O_NONBLOCK);
-               if (*fd < 0) {
-                       if (a->tree_enter_working_dir(a->tree) != 0) {
-                               archive_set_error(&a->archive, errno,
-                                   "Couldn't access %s", path);
-                               return (ARCHIVE_FAILED);
-                       }
-               }
+       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_WARN);
+       }
+       if (*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);
+       }
+       if (*fd < 0 && path == NULL) {
+               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                   "Can't open file to read extended attributes");
+               return (ARCHIVE_WARN);
        }
 
        if (*fd >= 0)