From 4014e2479c7b0273f15bd0c9c017c5fe859b0d8f Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Sun, 5 Jan 2025 21:43:11 +0200 Subject: [PATCH] xz: O_SEARCH cannot be used for fsync() 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 | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/xz/file_io.c b/src/xz/file_io.c index 9958b689..5048ef22 100644 --- a/src/xz/file_io.c +++ b/src/xz/file_io.c @@ -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),