@@ -16,7 +16,7 @@ use std::os::unix::net::UnixListener;
1616use std:: path:: { Path , PathBuf , StripPrefixError } ;
1717use std:: { fmt, io} ;
1818#[ cfg( all( unix, not( target_os = "android" ) ) ) ]
19- use uucore:: fsxattr:: copy_xattrs_fd ;
19+ use uucore:: fsxattr:: copy_xattrs ;
2020use uucore:: translate;
2121
2222use clap:: { Arg , ArgAction , ArgMatches , Command , builder:: ValueParser , value_parser} ;
@@ -1675,13 +1675,8 @@ fn handle_preserve<F: Fn() -> CopyResult<()>>(p: &Preserve, f: F) -> CopyResult<
16751675/// user-writable if needed and restoring its original permissions afterward. This avoids "Operation
16761676/// not permitted" errors on read-only files. Returns an error if permission or metadata operations fail,
16771677/// or if xattr copying fails.
1678- ///
1679- /// Uses file descriptor-based operations to avoid TOCTOU races during xattr copying.
16801678#[ cfg( all( unix, not( target_os = "android" ) ) ) ]
16811679fn copy_extended_attrs ( source : & Path , dest : & Path ) -> CopyResult < ( ) > {
1682- use std:: fs:: File ;
1683- use uucore:: fsxattr:: copy_xattrs;
1684-
16851680 let metadata = fs:: symlink_metadata ( dest) ?;
16861681
16871682 // Check if the destination file is currently read-only for the user.
@@ -1695,18 +1690,9 @@ fn copy_extended_attrs(source: &Path, dest: &Path) -> CopyResult<()> {
16951690 fs:: set_permissions ( dest, perms) ?;
16961691 }
16971692
1698- // Use file descriptor-based operations for regular files to avoid TOCTOU races.
1699- // For directories and symlinks, we must use path-based operations since:
1700- // - Directories cannot be opened with write mode for xattr operations
1701- // - Symlinks (especially dangling ones) cannot be opened via File::open
1702- let copy_xattrs_result = if metadata. is_file ( ) {
1703- // Open both files to pin their inodes, avoiding TOCTOU races during xattr operations
1704- let source_file = File :: open ( source) ?;
1705- let dest_file = OpenOptions :: new ( ) . write ( true ) . open ( dest) ?;
1706- copy_xattrs_fd ( & source_file, & dest_file)
1707- } else {
1708- copy_xattrs ( source, dest)
1709- } ;
1693+ // Perform the xattr copy and capture any potential error,
1694+ // so we can restore permissions before returning.
1695+ let copy_xattrs_result = copy_xattrs ( source, dest) ;
17101696
17111697 // Restore read-only if we changed it.
17121698 if was_readonly {
0 commit comments