]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Extend unreadable directory code to Linux (O_PATH) and SunOS (O_SEARCH)
authorMartin Matuska <martin@matuska.org>
Sun, 31 Mar 2019 10:43:26 +0000 (12:43 +0200)
committerMartin Matuska <martin@matuska.org>
Sun, 31 Mar 2019 10:43:51 +0000 (12:43 +0200)
libarchive/archive_read_disk_posix.c
libarchive/test/test_read_disk_directory_traversals.c

index 385f8e6e450a62f8244e2d789f5cfe564e9084b2..91ccccc7a9b6fd0d42060ebe696f891d59276d07 100644 (file)
@@ -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);
index c3666b85b1f41cec7202c30109405160a1a7322c..82579b23c22d49b8dddb040905bca1e21ae0163e 100644 (file)
@@ -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. */