From 68e34b662dad02af0f33c11fc3c44f0d2a7f81fd Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Sat, 18 Feb 2017 02:36:20 +0100 Subject: [PATCH] disk read: rework handling of paths for acls, xattrs and mac_metadata 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 --- .../archive_read_disk_entry_from_file.c | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/libarchive/archive_read_disk_entry_from_file.c b/libarchive/archive_read_disk_entry_from_file.c index b9cd8da90..e81c28e57 100644 --- a/libarchive/archive_read_disk_entry_from_file.c +++ b/libarchive/archive_read_disk_entry_from_file.c @@ -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) -- 2.47.2