Details
-
Bug
-
Resolution: Fixed
-
P4
-
13, 17, 20, 21
-
b26
-
x86_64
-
windows_10
Description
ADDITIONAL SYSTEM INFORMATION :
Windows 10 > 1703
A DESCRIPTION OF THE PROBLEM :
The solution for issueJDK-8221852 prevents the actual error from symlink creation from being relayed to the user in the mentioned environment.
The exception from the second attempt at symlink creation, the one with the flag allowing symlinks without elevation, is discarded unconditionally. However, Windows *appears* to check the flag/privileges situation first, and only then looks into whether the target already exists.
Thus, the exception from the second attempt should only be discarded if it is either ERROR_PRIVILEGE_NOT_HELD (developer mode not enabled) or ERROR_INVALID_PARAMETER (flag not supported). In any other case, the new error should be relayed to the calling code instead of the original one.
See problematic change at: https://github.com/openjdk/jdk/commit/5952e2bc6496e349874d9f8748b1bfda9a7e4cc4#diff-70b8da266a5d031447f4f390981470464c400a0b012591788f17f19ca19d336fR948
I also checked in the most recent jdk-21-ea build, and the problem persists. The symlink creation code on Windows seems unchanged since the mentioned commit.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create two files A and B by any means
2. Call Files.createSymbolicLink with the paths of A and B
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Exception FileAlreadyExistsException is thrown, stating that A (the would-be link) already exists.
ACTUAL -
On Windows, the exception is FileSystemException (stating that the client is missing a required privilege), even when developer mode is enabled. The actual exception is lost.
---------- BEGIN SOURCE ----------
import java.nio.file.Files;
import java.nio.file.Path;
public class Test {
public static void main(String[] args) throws Exception {
final var pA = Files.createTempFile("link", null);
final var pB = Files.createTempFile("target", null);
try {
Files.createSymbolicLink(pA, pB);
} catch (java.nio.file.FileAlreadyExistsException e) {
System.out.println("OK");
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The only workaround I have found is to manually check whether the target exists beforehand, but this is naturally racy.
FREQUENCY : always
Windows 10 > 1703
A DESCRIPTION OF THE PROBLEM :
The solution for issue
The exception from the second attempt at symlink creation, the one with the flag allowing symlinks without elevation, is discarded unconditionally. However, Windows *appears* to check the flag/privileges situation first, and only then looks into whether the target already exists.
Thus, the exception from the second attempt should only be discarded if it is either ERROR_PRIVILEGE_NOT_HELD (developer mode not enabled) or ERROR_INVALID_PARAMETER (flag not supported). In any other case, the new error should be relayed to the calling code instead of the original one.
See problematic change at: https://github.com/openjdk/jdk/commit/5952e2bc6496e349874d9f8748b1bfda9a7e4cc4#diff-70b8da266a5d031447f4f390981470464c400a0b012591788f17f19ca19d336fR948
I also checked in the most recent jdk-21-ea build, and the problem persists. The symlink creation code on Windows seems unchanged since the mentioned commit.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Create two files A and B by any means
2. Call Files.createSymbolicLink with the paths of A and B
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Exception FileAlreadyExistsException is thrown, stating that A (the would-be link) already exists.
ACTUAL -
On Windows, the exception is FileSystemException (stating that the client is missing a required privilege), even when developer mode is enabled. The actual exception is lost.
---------- BEGIN SOURCE ----------
import java.nio.file.Files;
import java.nio.file.Path;
public class Test {
public static void main(String[] args) throws Exception {
final var pA = Files.createTempFile("link", null);
final var pB = Files.createTempFile("target", null);
try {
Files.createSymbolicLink(pA, pB);
} catch (java.nio.file.FileAlreadyExistsException e) {
System.out.println("OK");
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The only workaround I have found is to manually check whether the target exists beforehand, but this is naturally racy.
FREQUENCY : always
Attachments
Issue Links
- relates to
-
JDK-8221852 SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE should be selected at runtime, not build time
-
- Closed
-