[Bug 50283] New: FILE_OPEN_REPARSE_POINT breaks error reporting for deletes of directories

WineHQ Bugzilla wine-bugs at winehq.org
Tue Dec 8 06:16:04 CST 2020


https://bugs.winehq.org/show_bug.cgi?id=50283

            Bug ID: 50283
           Summary: FILE_OPEN_REPARSE_POINT breaks error reporting for
                    deletes of directories
           Product: Wine-staging
           Version: unspecified
          Hardware: x86-64
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: -unknown
          Assignee: wine-bugs at winehq.org
          Reporter: martin at martin.st
                CC: erich.e.hoover at gmail.com, leslie_alistair at hotmail.com,
                    z.figura12 at gmail.com
      Distribution: ---

Created attachment 68840
  --> https://bugs.winehq.org/attachment.cgi?id=68840
Test program

In order to generically delete a file system entry, regardless of whether it is
a regular file, symlink or directory, one can open a handle to it and delete it
with a call to SetFileInformationByHandle(FileDispositionInfo). By opening the
handle with FILE_FLAG_OPEN_REPARSE_POINT, a potential symlink gets handled by
removing the symlink itself, not the target file it points to.

If a handle opened with the FILE_FLAG_OPEN_REPARSE_POINT flag set turns out to
be a directory, error reporting for the SetFileInformationByHandle call fails.
This is caused by [1] in combination with [2]. These two cases make O_SYMLINK,
which includes O_PATH, be added when opening the file descriptor which turns
out to be a directory. The O_PATH flag causes the later fdopendir() and
readdir() to not return anything, causing is_dir_empty [3] to indicate that the
directory is empty and removal will succeed, even though it doesn't.

This triggers errors in a std::filesystem testcase in libc++ [4], when checking
to make sure that attempts to remove a non-empty directory properly signals
errors.

[1]
https://github.com/wine-staging/wine-staging/blob/fce121fcd95380ca56c9d027be8719f3b32e1b9a/patches/ntdll-Junction_Points/0016-server-Properly-handle-file-symlink-deletion.patch#L47
[2]
https://github.com/wine-staging/wine-staging/blob/fce121fcd95380ca56c9d027be8719f3b32e1b9a/patches/ntdll-Junction_Points/0027-server-Implement-FILE_OPEN_REPARSE_POINT-option.patch#L36
[3]
https://source.winehq.org/git/wine.git/blob/fac1e40aaf0726a3e328a922cb496927548190cf:/server/fd.c#l2368
[4]
https://github.com/llvm/llvm-project/blob/1e260f955d3123351fc68de8c2dde02b1be6d14f/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp#L68-L70

The issue can be reproduced with the attached fairly minimal test program.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list