Skip to content

Fix an issue where SecureAction#getCanonicalPath can resolve paths to real paths#501

Open
pigelvy wants to merge 1 commit intoapache:masterfrom
pigelvy:patch-1
Open

Fix an issue where SecureAction#getCanonicalPath can resolve paths to real paths#501
pigelvy wants to merge 1 commit intoapache:masterfrom
pigelvy:patch-1

Conversation

@pigelvy
Copy link
Copy Markdown

@pigelvy pigelvy commented May 6, 2026

On Windows, if Apache Felix is run from a subst drive (e.g. "P:\felix" where "P:" is a "subst" drive to "C:\tmp"), some internal resources failed to be properly resolved on startup.

I noticed that, with Java 25, an exception occured in org.apache.felix.framework.Felix#handleJavaVersionChange().

ERROR: Bundle org.apache.felix.framework [0] The data file must be inside the data dir. Could not create framework: java.lang.NullPointerException: Cannot invoke "java.io.File.isFile()" because "dataFile" is null java.lang.NullPointerException: Cannot invoke "java.io.File.isFile()" because "dataFile" is null
        at org.apache.felix.framework.Felix.handleJavaVersionChange(Felix.java:1012)
        at org.apache.felix.framework.Felix.init(Felix.java:810)
        at org.apache.felix.framework.Felix.init(Felix.java:648)
        at org.apache.felix.main.Main.main(Main.java:289)

After some investigation and step-by-step debugging, it appeared that the issue is located in BundleCache#getSystemBundleDataFile(String) because the canonical paths are not resolved similarly. This causes the file to be detected as outside of it directory.

String dataFilePath = BundleCache.getSecureAction().getCanonicalPath(dataFile);
String dataDirPath = BundleCache.getSecureAction().getCanonicalPath(sbDir);
if (!dataFilePath.equals(dataDirPath) && !dataFilePath.startsWith(dataDirPath + File.separatorChar))
{
    throw new IllegalArgumentException("The data file must be inside the data dir.");
}

To prevent this verification from being too dependent on the underlying file-system and the resolution to real paths, this commit leverages java.nio.file.Path#normalize to sanitize the file path.

… the real paths

On Windows, if Apache Felix is run from a `subst` drive (e.g. "P:\felix" where "P:" is a "subst" drive to "C:\tmp"), some internal resources failed to be properly resolved on startup.

I noticed that, with Java 25, an exception occured in `org.apache.felix.framework.Felix#handleJavaVersionChange()`.
---
ERROR: Bundle org.apache.felix.framework [0] The data file must be inside the data dir.
Could not create framework: java.lang.NullPointerException: Cannot invoke "java.io.File.isFile()" because "dataFile" is null
java.lang.NullPointerException: Cannot invoke "java.io.File.isFile()" because "dataFile" is null
        at org.apache.felix.framework.Felix.handleJavaVersionChange(Felix.java:1012)
        at org.apache.felix.framework.Felix.init(Felix.java:810)
        at org.apache.felix.framework.Felix.init(Felix.java:648)
        at org.apache.felix.main.Main.main(Main.java:289)
---

After some investigation and step-by-step debugging, it appeared that the issue is located in `BundleCache#getSystemBundleDataFile(String)` because the canonical paths are not resolved similarly. This causes the file to be detected as outside of it directory.

```
String dataFilePath = BundleCache.getSecureAction().getCanonicalPath(dataFile);
        String dataDirPath = BundleCache.getSecureAction().getCanonicalPath(sbDir);
        if (!dataFilePath.equals(dataDirPath) && !dataFilePath.startsWith(dataDirPath + File.separatorChar))
        {
            throw new IllegalArgumentException("The data file must be inside the data dir.");
        }
```

To prevent this verification from being too dependent on the underlying file-system and the resolution of real paths, this commit leverages `java.nio.file.Path#normalize` to sanitize the file path.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant