Hello core-libs-dev,

I was asked to help look into JDK-8232092 by Christian Stein (the bug 
reporter), and since I don't have an OpenJDK account yet I'm sharing my 
findings on the issue here. I looked into two separate issues that might cause 
FileSystemProvider.checkAccess to return an incorrect result as reported. 

The first issue seems related to substituted directories with volumes, or 
virtual drives on Windows. The problem happens if the Windows 
GetVolumePathNameW API is called with a virtual drive letter in the path, 
causing the API to return ERROR_INVALID_PARAMETER or error code 87. The code in 
WindowsFileStore::create makes a call to WindowsLinkSupport::getFinalPath, 
however the getFinalPath method will avoid expanding the virtual drive path, by 
calling GetFinalPathNameByHandle, because the path isn't a symbolic link. The 
existing code in WindowsFileStore::create currently checks for the ErrorLevel 
of ERROR_DIR_NOT_ROOT, and it properly calls the path expansion API, however it 
doesn't check for ERROR_INVALID_PARAMETER which might happen if a path with 
virtual drive letter is used.

We can follow the steps below to reproduce the issue:
- Have a writeable directory on Windows, e.g. C:\Temp
- Run "subst T: C:\Temp" on the command line to create the virtual drive T for 
C:\Temp
- Check with "cacls T:" and "cacls C:\Temp" that you have the exact same access 
control permissions
- Run "FileSystems.getDefault().provider().checkAccess(Path.of("T:\\"), 
java.nio.file.AccessMode.WRITE)" in jshell and you'll see an Exception 
java.nio.file.FileSystemException: T:\: The parameter is incorrect. Running the 
same command on C:\\Temp will return without an exception.

I've attached at the bottom of this email a simple patch that address the 
virtual drive issue. There might be a better way to fix this issue so any 
feedback is appreciated.

The second issue reported is using a virtual drive with the ImDisk utility to 
create a Virtual RAM Disk on Windows (Z: drive in the bug report). As mentioned 
in the bug report the failure is slightly different, in this case 
GetFinalPathNameByHandleW is called and the API returns ERROR_INVALID_FUNCTION. 
This error is caused by the third-party utility design/implementation. With 
ImDisk virtual disks, applications that rely on Windows Volume Mount Manager 
APIs, like GetFinalPathNameByHandleW, will fail because ImDisk does not 
interact with Windows Volume Mount Manager at all, it effectively bypasses it. 
Essentially, GetFinalPathNameByHandle and few other APIs will never work 
properly with ImDisk virtual drives.

Cheers,
Nikola Grcevski
Microsoft

diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java 
b/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java
index acbb2c15f2a..9b4b4117b24 100644
--- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java
+++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java
@@ -79,10 +79,12 @@ class WindowsFileStore
             // volume that the link is on so we need to call it with the
             // final target
             String target = WindowsLinkSupport.getFinalPath(file, true);
+                        
             try {
                 return createFromPath(target);
             } catch (WindowsException e) {
-                if (e.lastError() != ERROR_DIR_NOT_ROOT)
+                if (e.lastError() != ERROR_DIR_NOT_ROOT && 
+                    e.lastError() != ERROR_INVALID_PARAMETER)
                     throw e;
                 target = WindowsLinkSupport.getFinalPath(file);
                 if (target == null)

Reply via email to