From: Martin Matuska Date: Mon, 24 Nov 2025 13:02:20 +0000 (+0100) Subject: Partially revert "Merge pull request #2679 from AZero13/error" X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aac59c1bd5e64bc007aac5e2cbf37f149450ab38;p=thirdparty%2Flibarchive.git Partially revert "Merge pull request #2679 from AZero13/error" This reverts commit d8aaf88c9feab047139df4cae60d845764a2480a, reversing changes made to ee49ac81068f93754f004368f2cc72c95a8bf056. tree_reopen() and tree_dup() return NULL only of they are unable to allocate memory. Otherwise libarchive enters ARCHIVE_FATAL if trying to walk an enterable but unreadable directory. __archive_ensure_cloexec_flag() operates only on fd >= 0 so there is no need to skip it I have reimplemented the check around fdopendir() Reported by: Christian Weisgerber from OpenBSD --- diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index 7cd292f25..94fa8fef9 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -2018,11 +2018,8 @@ tree_dup(int fd) } #endif /* F_DUPFD_CLOEXEC */ new_fd = dup(fd); - if (new_fd != -1) { - __archive_ensure_cloexec_flag(new_fd); - return (new_fd); - } - return (-1); + __archive_ensure_cloexec_flag(new_fd); + return (new_fd); } /* @@ -2144,16 +2141,11 @@ tree_reopen(struct tree *t, const char *path, int restore_time) * so try again for execute. The consequences of not opening this are * unhelpful and unnecessary errors later. */ - if (t->initial_dir_fd < 0) { + if (t->initial_dir_fd < 0) t->initial_dir_fd = open(".", o_flag | O_CLOEXEC); - if (t->initial_dir_fd < 0) - return NULL; - } #endif __archive_ensure_cloexec_flag(t->initial_dir_fd); t->working_dir_fd = tree_dup(t->initial_dir_fd); - if (t->working_dir_fd < 0) - return NULL; return (t); } @@ -2359,15 +2351,20 @@ static int tree_dir_next_posix(struct tree *t) { int r; +#if defined(HAVE_FDOPENDIR) + int fd; +#endif const char *name; size_t namelen; if (t->d == NULL) { #if defined(HAVE_FDOPENDIR) - int fd = tree_dup(t->working_dir_fd); - if (fd != -1) - t->d = fdopendir(fd); + if (t->working_dir_fd >= 0) { + fd = tree_dup(t->working_dir_fd); + if (fd != -1) + t->d = fdopendir(fd); + } #else /* HAVE_FDOPENDIR */ if (tree_enter_working_dir(t) == 0) { t->d = opendir("."); diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c index ded13bee7..96d2c71f4 100644 --- a/libarchive/archive_read_support_format_mtree.c +++ b/libarchive/archive_read_support_format_mtree.c @@ -1254,7 +1254,7 @@ parse_file(struct archive_read *a, struct archive_entry *entry, archive_entry_filetype(entry) == AE_IFDIR) { mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(mtree->fd); - if (mtree->fd < 0 && ( + if (mtree->fd == -1 && ( #if defined(_WIN32) && !defined(__CYGWIN__) /* * On Windows, attempting to open a file with an diff --git a/libarchive/archive_write_disk_posix.c b/libarchive/archive_write_disk_posix.c index cd2562030..d1f043d24 100644 --- a/libarchive/archive_write_disk_posix.c +++ b/libarchive/archive_write_disk_posix.c @@ -2561,9 +2561,9 @@ _archive_write_disk_close(struct archive *_a) * for directories. For other file types * we need to verify via fstat() or lstat() */ - if (fd < 0 || p->filetype != AE_IFDIR) { + if (fd == -1 || p->filetype != AE_IFDIR) { #if HAVE_FSTAT - if (fd >= 0 && ( + if (fd > 0 && ( fstat(fd, &st) != 0 || la_verify_filetype(st.st_mode, p->filetype) == 0)) { @@ -4447,7 +4447,7 @@ fixup_appledouble(struct archive_write_disk *a, const char *pathname) */ fd = open(pathname, O_RDONLY | O_BINARY | O_CLOEXEC); __archive_ensure_cloexec_flag(fd); - if (fd < 0) { + if (fd == -1) { archive_set_error(&a->archive, errno, "Failed to open a restoring file"); ret = ARCHIVE_WARN;