-
Notifications
You must be signed in to change notification settings - Fork 494
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Symlink reparse points not resolved above the mount point #454
Comments
If I understand your scenario correctly, you are trying to create a relative symbolic link that points outside the file system. I believe that this is not allowed on Windows, because a relative symbolic link must point inside the file system. |
Note that I'm trying to point at the mount point also, which lies inside the file system!
I think that both, junction mount points and symlinks allow to cross file system boundaries on Windows by using relative target paths. Look (I used one VHD and WinFPS, which involves three file systems!):
|
Can you try |
Sure! On top of it, I can show you the fields already processed with an additional tool.
Tested in:
Output is identical for both directories (I checked just in case we had a bug). Here, I only included one copy of it. 1. SYMLINK - SAME FILE SYSTEM
2. SYMLINK - CROSSING FILE SYSTEMS
3. JUNCTION - CROSSING FILE SYSTEMSOnly tested in C:\Environment\MOUNT_POINT
|
Yes, junctions have some limitations:
Earlier you posted this relative symbolic link across a VHD boundary. (I am assuming that the VHD was formatted with NTFS and mounted on a directory.) Can you also post the
Indeed symbolic links have the BTW, you can have a relative symbolic link that points to |
Yes, sure! Mind you, no big surprises here. Also, it is just as your said: I formated the drive in NTFS and mounted it as directory.
After these checks, I'm pretty sure they are not confined to file system, and I think it should work for all those cases. Besides, the solver is failing to find the root of the virtual file system, so at least there is something off there. Not super sure if my code is doing something wrong though. Could you check the same "mklink /D dot ." test on a reference implementation, just in case? That would at least narrow down what is going on, whether it is in my side on in WinFSP.
Clever! Indeed, I wasn't trying that in the example, I just added an extra level out of a whim, but makes a lot of sense.
|
Thank you for the new output, which seems to confirm that relative symlinks are supposed to work across file system boundaries. If we were to change this behavior in WinFsp and allow relative symlinks to cross file system boundaries we would have to consider complications such as backwards compatibility and security. For example, existing file systems that support reparse points may fully expect the current WinFsp behavior and we should not change that behavior without explicit consent. I would likely do this by adding a new field (e.g. Reparse point resolution happens in user mode at FspFileSystemResolveReparsePointsInternal. Dot handling happens at this location. The kernel mode FSD also checks any returned symlink for validity at this location. These locations and likely others would have to be changed. All existing tests should pass (unless they test for the opposite behavior!) and we should likely devise new tests for the new behavior under I currently have no time to work on this. Perhaps you might consider taking a stab at it on your own? |
I just ran into this limitation as well when looking for a potential solution to a problem of one of my project's users. This solution (a relative symlink crossing the boundary from a read-only file system to a writeable volume) works fine on Linux, but not using WinFsp. Unfortunately I don't currently have the time to dig into the WinFsp code myself, especially given my lack of Windows development experience. |
Actually, the I/O manager reparses "\" targets on the device of the opened path, not the root of the filesystem. For example, if the opened path is "\Device\HarddiskVolume2\Mounts\MountPoint\Symlink", and "Symlink" targets "\", then it resolves to "\Device\HarddiskVolume2\". There's a lot of careful code that handles system mount points (i.e. This design also supports junction mount points and symlinks in remote paths. The server side is always responsible for resolving junctions, which must target a local path on the server. The client side is always responsible for resolving symlinks (and may disallow the target type -- L2L, L2R, R2L, R2R). For reparsing a symlink, the server sends a message back to the client with the opened path on the share and the symlink target path. The opened path will include any number of traversed junctions. They remain in the opened path like regular directories as far as the client is concerned. Note that relative symlinks can resolve differently depending on the mount point that's used. They may even fail to resolve when accessed from a particular mount point. For example, if "\Device\HarddiskVolume3\Symlink" targets "..", path resolution will fail as invalid reparse data if the system tries to traverse "Symlink" via the mount point "\Device\HarddiskVolume3\". On the other hand, if the opened path is "\Device\HarddiskVolume2\Mounts\MountPoint\Symlink", for which "\Device\HarddiskVolume2\Mounts\MountPoint" is a junction that targets "\Device\HarddiskVolume3\", then the path will be successfully resolved as "\Device\HarddiskVolume2\Mounts". |
Bug Report
I think there is something loose in the code that solves symlinks.
When testing with directories:
The name of the file cannot be resolved by the system.
Absolute paths work OK.
The symlinks that trigger this behavior work OK when moved down the file hierarchy.
How to Reproduce
Case 1 - Link to dot
Case 2 - Link to dot-dot
Behaviors
It would be expected to be able to access both, the mount point directory and locations out of it by using relative symlinks (already possible with absolute paths).
Environment
The text was updated successfully, but these errors were encountered: