]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
xz: O_SEARCH cannot be used for fsync()
authorLasse Collin <lasse.collin@tukaani.org>
Sun, 5 Jan 2025 19:43:11 +0000 (21:43 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Sun, 5 Jan 2025 19:43:11 +0000 (21:43 +0200)
Opening a directory with O_SEARCH results in a file descriptor that can
be used with functions like openat(). Such a file descriptor cannot be
used with fsync(). Use O_RDONLY instead.

In musl, O_SEARCH becomes Linux-specific O_PATH. A file descriptor
from O_PATH doesn't allow fsync().

Seems that it's not possible to fsync() a directory that has write
and search permissions but not read permission.

Fixes: 2a9e91d796d091740489d951fa7780525e4275f1
src/xz/file_io.c

index 9958b6890f19bb0bf74af1c4ce2a486ab9370dc0..5048ef220eb6146e8dace1c8eb55c831d00ef97c 100644 (file)
@@ -69,10 +69,6 @@ static bool warn_fchown;
 #      define O_NOCTTY 0
 #endif
 
-#ifndef O_SEARCH
-#      define O_SEARCH O_RDONLY
-#endif
-
 #ifndef O_DIRECTORY
 #      define O_DIRECTORY 0
 #endif
@@ -890,7 +886,7 @@ io_open_dest_real(file_pair *pair)
                        // to a directory. (We opened the source file
                        // already but directories might have been renamed
                        // after the source file was opened.)
-                       pair->dir_fd = open(dir_name, O_SEARCH | O_DIRECTORY
+                       pair->dir_fd = open(dir_name, O_RDONLY | O_DIRECTORY
                                        | O_NOCTTY | O_NONBLOCK);
                        if (pair->dir_fd == -1) {
                                // Since we did open the source file
@@ -900,12 +896,15 @@ io_open_dest_real(file_pair *pair)
                                //
                                // In an odd case, the directory has write
                                // and search permissions but not read
-                               // permission (d-wx------), and O_SEARCH is
-                               // actually O_RDONLY. Then we would be able
-                               // to create a new file and only the directory
-                               // syncing would be impossible. But let's be
-                               // strict about syncing and require users to
-                               // explicitly disable it if they don't want it.
+                               // permission (d-wx------). Then we would be
+                               // able to create a new file and only the
+                               // directory syncing would be impossible. But
+                               // let's be strict about syncing and require
+                               // users to explicitly disable it if they
+                               // don't want it.
+                               //
+                               // NOTE: O_SEARCH doesn't allow fsync().
+                               // musl maps O_SEARCH to O_PATH.
                                message_error(_("%s: Opening the directory "
                                        "failed: %s"),
                                        tuklib_mask_nonprint(dir_name),