From: Martin Matuska Date: Sun, 31 Mar 2019 10:43:26 +0000 (+0200) Subject: Extend unreadable directory code to Linux (O_PATH) and SunOS (O_SEARCH) X-Git-Tag: v3.4.0~91 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9112ff6c9242204a72e8ee756fd6346a4005111f;p=thirdparty%2Flibarchive.git Extend unreadable directory code to Linux (O_PATH) and SunOS (O_SEARCH) --- diff --git a/libarchive/archive_read_disk_posix.c b/libarchive/archive_read_disk_posix.c index 385f8e6e4..91ccccc7a 100644 --- a/libarchive/archive_read_disk_posix.c +++ b/libarchive/archive_read_disk_posix.c @@ -2164,6 +2164,17 @@ tree_open(const char *path, int symlink_mode, int restore_time) static struct tree * tree_reopen(struct tree *t, const char *path, int restore_time) { +#if defined(O_PATH) + /* Linux */ + const int o_flag = O_PATH; +#elif defined(O_SEARCH) + /* SunOS */ + const int o_flag = O_SEARCH; +#elif defined(O_EXEC) + /* FreeBSD */ + const int o_flag = O_EXEC; +#endif + t->flags = (restore_time != 0)?needsRestoreTimes:0; t->flags |= onInitialDir; t->visit_type = 0; @@ -2185,14 +2196,14 @@ tree_reopen(struct tree *t, const char *path, int restore_time) t->stack->flags = needsFirstVisit; t->maxOpenCount = t->openCount = 1; t->initial_dir_fd = open(".", O_RDONLY | O_CLOEXEC); -#ifdef O_EXEC +#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC) /* * Most likely reason to fail opening "." is that it's not readable, * so try again for execute. The consequences of not opening this are * unhelpful and unnecessary errors later. */ if (t->initial_dir_fd < 0) - t->initial_dir_fd = open(".", O_EXEC | O_CLOEXEC); + t->initial_dir_fd = open(".", o_flag | O_CLOEXEC); #endif __archive_ensure_cloexec_flag(t->initial_dir_fd); t->working_dir_fd = tree_dup(t->initial_dir_fd); diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c index c3666b85b..82579b23c 100644 --- a/libarchive/test/test_read_disk_directory_traversals.c +++ b/libarchive/test/test_read_disk_directory_traversals.c @@ -1737,7 +1737,8 @@ test_parent(void) /* * Test4: Traverse lock/lock2/dir1 from inside lock. * - * This test is expected to fail on platforms with no O_EXEC, because + * This test is expected to fail on platforms with no O_EXEC or + * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because * the current traversal code can't handle the case where it can't * obtain an open fd for the initial current directory. We need to * check that condition here, because if O_EXEC _does_ exist, we don't @@ -1751,7 +1752,7 @@ test_parent(void) archive_entry_clear(ae); r = archive_read_next_header2(a, ae); if (r == ARCHIVE_FAILED) { -#ifdef O_EXEC +#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC) assertEqualIntA(a, ARCHIVE_OK, r); #endif /* Close the disk object. */