[Bug 51059] New: Incorrect semantics of FILE_OPEN_REPARSE_POINT on Linux

WineHQ Bugzilla wine-bugs at winehq.org
Sun Apr 25 19:54:37 CDT 2021


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

            Bug ID: 51059
           Summary: Incorrect semantics of FILE_OPEN_REPARSE_POINT on
                    Linux
           Product: Wine-staging
           Version: 6.7
          Hardware: x86-64
                OS: Linux
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: -unknown
          Assignee: wine-bugs at winehq.org
          Reporter: jinoh.kang.kr at gmail.com
                CC: erich.e.hoover at gmail.com, leslie_alistair at hotmail.com,
                    z.figura12 at gmail.com
      Distribution: ---

This bug affects the Cygwin installer (https://cygwin.com/setup-x86_64.exe);
specifically, it fails to verify SHA512 checksums of downloaded packages.

(Source at
https://cygwin.com/git/?p=cygwin-apps/setup.git;a=blob;f=package_source.cc,
 in method packagesource::check_sha512)

Running the installer with WINEDEBUG=trace+file,trace+server reports:

    CreateFileW ("XXXX.tar.xz") [1]
    NtCreateFile ("XXXX.tar.xz", w/o FILE_OPEN_REPARSE_POINT) [1]
    CreateFileW return [1]
    NtQueryInformationFile FileBasicInformation [1]
    (server)close_handle [1]

    NtCreateFile ("XXXX.tar.xz", w/ FILE_OPEN_REPARSE_POINT) [2]
    NtReadFile [2] -> STATUS_INVALID_HANDLE

The square brackets denote file handles. Handle reuse bug has been
ruled out.

This bug can be traced to an incorrect FILE_OPEN_REPARSE_POINT implementation
in Wine-staging, in
"ntdll-Junction_Points/0016-server-Implement-FILE_OPEN_REPARSE_POINT-option.patch":

> diff --git a/server/fd.c b/server/fd.c
> index 4f43f41fb31..a01d4c9c0f7 100644
> --- a/server/fd.c
> +++ b/server/fd.c
> @@ -107,6 +107,10 @@
>  #include "winioctl.h"
>  #include "ddk/wdm.h"
>  
> +#if !defined(O_SYMLINK) && defined(O_PATH)
> +# define O_SYMLINK (O_NOFOLLOW | O_PATH)
> +#endif

On Linux, read/write/ioctl/... operations on an O_PATH descriptor will
fail with EBADF, which is then translated as STATUS_INVALID_HANDLE to the
application.

> +
>  #if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_EPOLL_CREATE)
>  # include <sys/epoll.h>
>  # define USE_EPOLL
> @@ -1958,6 +1962,11 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
>      }
>      else rw_mode = O_RDONLY;
>  
> +#if defined(O_SYMLINK)
> +    if ((options & FILE_OPEN_REPARSE_POINT) && !(flags & O_CREAT))
> +        flags |= O_SYMLINK;

Another difference is that O_PATH semantics override
O_RDONLY/O_WRONLY/O_RDWR, even if the target file isn't _actually_ a
symbolic link.

To properly implement it on Linux we should:

1. open with O_PATH.
2. check if the file is really a symlink (via fstat?).
3. if not, reopen via /proc/self/fd/%u (now w/o O_NOFOLLOW|O_PATH).

Note that this isn't an issue on XNU (macOS), where O_SYMLINK has an
equivalent semantics to FILE_OPEN_REPARSE_POINT.

-- 
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