libuv/src
Wade Brainerd 1d9c13f1f7 win, fs: fix non-symlink reparse points
Fixes uv_fs_stat and uv_fs_lstat returning EINVAL when invoked on a
non-symlink reparse point.

1. Only tries to read symlinks when invoked via lstat (do_lstat == 1).

Rationale is that only lstat can set S_IFLNK because when a file is
tested by stat, symlinks are resolved by the OS and the returned file
must be real. Note that broken symlinks fail at CreateFile.

FILE_ATTRIBUTE_REPARSE_POINT is used by filesystem drivers for purposes
besides symlinks, and uv_fs_stat fails when invoked on these files
because fs__readlink_handle returns ERROR_SYMLINK_NOT_SUPPORTED. By
ignoring the attribute in uv_fs_stat, these files are now handled
correctly.

2. Modifies the logic added to fs__stat_handle to fix #995 as follows:

A failed fs__readlink_handle on a file with a reparse point indicates
that the file is not a symlink. The fix for #995 added code to fall
through and behave as with a normal file in this case. However, this is
not correct because lstat had opened the file with
FILE_FLAG_OPEN_REPARSE_POINT, preventing the filesystem from acting
based on the reparse point contents.

The fix makes fs__stat_handle fail back to the higher level
fs__stat_impl, which sets do_lstat to 0 and re-opens the file without
FILE_FLAG_OPEN_REPARSE_POINT, allowing normal filesystem processing to
take place.

This is also a slightly cleaner solution as symlink fallback is only
handled in one place (fs__stat_impl) instead of two (fs__stat_impl and
fs__stat_handle).

Note that the error tested in the fix for #995,
ERROR_NOT_A_REPARSE_POINT, is not actually returned by Windows in the
case of a non-symlink reparse point. I attempted to reproduce the error
by repeating the test steps in the issue but failed. However, the the
fix logic is preserved out of caution.

3. Adds tests to fs-test.c for the above two changes.

Thorough testing requires some non-trivial setup - like an OSX computer
on the LAN or a custom filesystem driver - so these tests are left
commented out for manual invocation.

PR-URL: https://github.com/libuv/libuv/pull/1522
Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
2017-10-03 16:36:32 +02:00
..
unix unix: retry on ENOBUFS in sendmsg(2) 2017-10-02 15:51:39 -04:00
win win, fs: fix non-symlink reparse points 2017-10-03 16:36:32 +02:00
fs-poll.c unix, win: count null byte on UV_ENOBUFS 2016-03-03 09:23:10 +01:00
heap-inl.h heap: fix heap_remove() 2014-05-23 20:04:42 +04:00
inet.c win: use the MSVC provided snprintf where possible 2015-09-29 09:01:33 +02:00
queue.h unix: use QUEUE_MOVE when iterating over lists 2015-10-08 21:47:43 +02:00
threadpool.c unix,windows: refactor request init logic 2017-03-21 16:14:09 +01:00
uv-common.c fs: fix crash in uv_fs_scandir_next 2017-01-17 21:15:43 -06:00
uv-common.h unix,windows: refactor request init logic 2017-03-21 16:14:09 +01:00
version.c core: add UV_VERSION_HEX macro 2015-06-29 23:08:41 +02:00