8056243: OptimisticTypePersistence should refuse to work in symlinked directories
authorattila
Thu, 28 Aug 2014 16:38:23 +0200
changeset 26253 059266c07564
parent 26252 5a4c8ce0358f
child 26254 14591ffc0c61
child 26373 cd907cf7bf7a
8056243: OptimisticTypePersistence should refuse to work in symlinked directories Reviewed-by: lagergren, sundar
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java	Wed Aug 27 14:27:56 2014 +0530
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/OptimisticTypesPersistence.java	Thu Aug 28 16:38:23 2014 +0200
@@ -33,6 +33,7 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.net.URL;
+import java.nio.file.Files;
 import java.security.AccessController;
 import java.security.MessageDigest;
 import java.security.PrivilegedAction;
@@ -54,6 +55,9 @@
  * type info persistence altogether by specifying the {@code nashorn.typeInfo.disabled} system property.
  */
 public final class OptimisticTypesPersistence {
+    // The name of the default subdirectory within the system cache directory where we store type info.
+    private static final String DEFAULT_CACHE_SUBDIR_NAME = "com.oracle.java.NashornTypeInfo";
+    // The directory where we cache type info
     private static final File cacheDir = createCacheDir();
     // In-process locks to make sure we don't have a cross-thread race condition manipulating any file.
     private static final Object[] locks = cacheDir == null ? null : createLockArray();
@@ -193,7 +197,11 @@
                 } else {
                     // When no directory is explicitly specified, get an operating system specific cache directory,
                     // and create "com.oracle.java.NashornTypeInfo" in it.
-                    dir = new File(getCacheDirBase(), "com.oracle.java.NashornTypeInfo");
+                    final File systemCacheDir = getSystemCacheDir();
+                    dir = new File(systemCacheDir, DEFAULT_CACHE_SUBDIR_NAME);
+                    if (isSymbolicLink(dir)) {
+                        return null;
+                    }
                 }
                 final String versionDirName;
                 try {
@@ -203,6 +211,9 @@
                     return null;
                 }
                 final File versionDir = new File(dir, versionDirName);
+                if (isSymbolicLink(versionDir)) {
+                    return null;
+                }
                 versionDir.mkdirs();
                 if(versionDir.isDirectory()) {
                     getLogger().info("Optimistic type persistence directory is " + versionDir);
@@ -218,7 +229,7 @@
      * Returns an operating system specific root directory for cache files.
      * @return an operating system specific root directory for cache files.
      */
-    private static File getCacheDirBase() {
+    private static File getSystemCacheDir() {
         final String os = System.getProperty("os.name", "generic");
         if("Mac OS X".equals(os)) {
             // Mac OS X stores caches in ~/Library/Caches
@@ -291,6 +302,19 @@
         return currentMax;
     }
 
+    /**
+     * Returns true if the specified file is a symbolic link, and also logs a warning if it is.
+     * @param file the file
+     * @return true if file is a symbolic link, false otherwise.
+     */
+    private static boolean isSymbolicLink(final File file) {
+        if (Files.isSymbolicLink(file.toPath())) {
+            getLogger().warning("Directory " + file + " is a symlink");
+            return true;
+        }
+        return false;
+    }
+
     private static Object[] createLockArray() {
         final Object[] lockArray = new Object[Runtime.getRuntime().availableProcessors() * 2];
         for (int i = 0; i < lockArray.length; ++i) {