RFR: 8352728: InternalError loading java.security due to Windows parent folder permissions [v8]
Francisco Ferrari Bihurriet
fferrari at openjdk.org
Thu Oct 30 23:07:23 UTC 2025
> Hi, this is a proposal to fix 8352728.
>
> The main idea is to replace [`java.nio.file.Path::toRealPath`](https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/nio/file/Path.html#toRealPath(java.nio.file.LinkOption...)) by [`java.io.File::getCanonicalPath`](https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/io/File.html#getCanonicalPath()) for path canonicalization purposes. The rationale behind this decision is the following:
>
> 1. In _Windows_, `File::getCanonicalPath` handles restricted permissions in parent directories. Contrarily, `Path::toRealPath` fails with `AccessDeniedException`.
> 2. In _Linux_, `File::getCanonicalPath` handles non-regular files (e.g. `/dev/stdin`). Contrarily, `Path::toRealPath` fails with `NoSuchFileException`.
>
> #### Windows Case
>
> @martinuy and I tracked down the `File::getCanonicalPath` vs `Path::toRealPath` behaviour differences in _Windows_. Both methods end up calling the [`FindFirstFileW`](https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfilew) API inside a loop for each parent directory in the path, until they include the leaf:
>
> * [`File::getCanonicalPath`](https://github.com/openjdk/jdk/blob/jdk-24-ga/src/java.base/share/classes/java/io/File.java#L618 "src/java.base/share/classes/java/io/File.java:618") goes through the following stack into `FindFirstFileW`:
> * [`WinNTFileSystem::canonicalize`](https://github.com/openjdk/jdk/blob/jdk-24-ga/src/java.base/windows/classes/java/io/WinNTFileSystem.java#L473 "src/java.base/windows/classes/java/io/WinNTFileSystem.java:473")
> * [`WinNTFileSystem::canonicalize0`](https://github.com/openjdk/jdk/blob/jdk-24-ga/src/java.base/windows/native/libjava/WinNTFileSystem_md.c#L288 "src/java.base/windows/native/libjava/WinNTFileSystem_md.c:288")
> * [`wcanonicalize`](https://github.com/openjdk/jdk/blob/jdk-24-ga/src/java.base/windows/native/libjava/canonicalize_md.c#L233 "src/java.base/windows/native/libjava/canonicalize_md.c:233") (here is the loop)
> * If `FindFirstFileW` fails with `ERROR_ACCESS_DENIED`, `lastErrorReportable` is consulted, the error is [considered non-reportable](https://github.com/openjdk/jdk/blob/jdk-24-ga/src/java.base/windows/native/libjava/canonicalize_md.c#L139 "src/java.base/windows/native/libjava/canonicalize_md.c:139") and the iteration is stopped [here](https://github.com/openjdk/jdk/blob/jdk-24-ga/src/java.base/windows/native/libjava/canonicalize_md.c#L246-L250 "src/java.base/windows/native/libjava/c...
Francisco Ferrari Bihurriet has updated the pull request incrementally with one additional commit since the last revision:
Detect cyclic includes with Files::isSameFile
checkCyclicInclude() is invoked after we successfully get an InputStream
for the path to avoid skipping the same IOException several times inside
checkCyclicInclude() if the path doesn't exist.
Also, perform symlinks resolution only in the following cases:
• When we need to resolve a relative include
• For clarity to the user in logging messages
• For clarity to the user in exception messages
In the first case, the resolution is a requirement, in the last two
cases it is a nice-to-have. But given the last two are exceptional
cases anyway, we let any resolution error bubble up.
-------------
Changes:
- all: https://git.openjdk.org/jdk/pull/24465/files
- new: https://git.openjdk.org/jdk/pull/24465/files/4e77fb36..a8d865c4
Webrevs:
- full: https://webrevs.openjdk.org/?repo=jdk&pr=24465&range=07
- incr: https://webrevs.openjdk.org/?repo=jdk&pr=24465&range=06-07
Stats: 41 lines in 1 file changed: 26 ins; 9 del; 6 mod
Patch: https://git.openjdk.org/jdk/pull/24465.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/24465/head:pull/24465
PR: https://git.openjdk.org/jdk/pull/24465
More information about the security-dev
mailing list