diff -u new/src/java.base/share/classes/java/io/FilePermission.java new/src/java.base/share/classes/java/io/FilePermission.java
--- new/src/java.base/share/classes/java/io/FilePermission.java 2016-08-25 11:28:24.583447700 +0800
+++ new/src/java.base/share/classes/java/io/FilePermission.java 2016-09-01 22:20:56.770074200 +0800
@@ -33,8 +33,9 @@
import java.util.StringJoiner;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
+import jdk.internal.misc.JavaIOFilePermissionAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.nio.fs.DefaultFileSystemProvider;
import sun.security.action.GetPropertyAction;
import sun.security.util.FilePermCompat;
@@ -262,35 +263,32 @@
}
static {
- FilePermCompat.newPermPlusAltPathFunction = new Function<>() {
- @Override
- public FilePermission apply(FilePermission input) {
- if (input.npath2 == null && !input.allFiles) {
- Path npath2 = altPath(input.npath);
- if (npath2 != null) {
- FilePermission np = new FilePermission(input);
- np.npath2 = npath2;
- return np;
+ SharedSecrets.setJavaIOFilePermissionAccess(
+ new JavaIOFilePermissionAccess() {
+ public FilePermission newPermPlusAltPath(FilePermission input) {
+ if (input.npath2 == null && !input.allFiles) {
+ Path npath2 = altPath(input.npath);
+ if (npath2 != null) {
+ FilePermission np = new FilePermission(input);
+ np.npath2 = npath2;
+ return np;
+ }
}
+ return input;
}
- return input;
- }
- };
-
- FilePermCompat.newPermUsingAltPathFunction = new Function<>() {
- @Override
- public FilePermission apply(FilePermission input) {
- if (!input.allFiles) {
- Path npath2 = altPath(input.npath);
- if (npath2 != null) {
- FilePermission np = new FilePermission(input);
- np.npath = npath2;
- return np;
+ public FilePermission newPermUsingAltPath(FilePermission input) {
+ if (!input.allFiles) {
+ Path npath2 = altPath(input.npath);
+ if (npath2 != null) {
+ FilePermission np = new FilePermission(input);
+ np.npath = npath2;
+ return np;
+ }
}
+ return null;
}
- return null;
}
- };
+ );
}
/**
diff -u new/src/java.base/share/classes/java/security/AccessControlContext.java new/src/java.base/share/classes/java/security/AccessControlContext.java
--- new/src/java.base/share/classes/java/security/AccessControlContext.java 2016-08-25 11:28:32.274093700 +0800
+++ new/src/java.base/share/classes/java/security/AccessControlContext.java 2016-09-01 22:21:03.570121100 +0800
@@ -446,7 +446,7 @@
}
for (int i=0; i< context.length; i++) {
- if (context[i] != null && !context[i].impliesWithAltFP(perm)) {
+ if (context[i] != null && !context[i].impliesWithAltFilePerm(perm)) {
if (dumpDebug) {
debug.println("access denied " + perm);
}
diff -u new/src/java.base/share/classes/java/security/ProtectionDomain.java new/src/java.base/share/classes/java/security/ProtectionDomain.java
--- new/src/java.base/share/classes/java/security/ProtectionDomain.java 2016-08-25 11:28:40.058188400 +0800
+++ new/src/java.base/share/classes/java/security/ProtectionDomain.java 2016-09-01 22:21:10.803595400 +0800
@@ -304,13 +304,11 @@
}
if (!staticPermissions &&
- Policy.getPolicyNoCheck().implies(this, perm)) {
+ Policy.getPolicyNoCheck().implies(this, perm)) {
return true;
}
if (permissions != null) {
- if (permissions.implies(perm)) {
- return true;
- }
+ return permissions.implies(perm);
}
return false;
@@ -326,7 +324,7 @@
* This method is called by {@link AccessControlContext#checkPermission}
* and not intended to be called by an application.
*/
- boolean impliesWithAltFP(Permission perm) {
+ boolean impliesWithAltFilePerm(Permission perm) {
// If this is a subclass of ProtectionDomain. Call the old method.
if (!FilePermCompat.compat || getClass() != ProtectionDomain.class) {
reverted:
--- new/src/java.base/share/classes/sun/security/util/IOUtils.java 2016-08-25 11:29:03.263792600 +0800
+++ old/src/java.base/share/classes/sun/security/util/IOUtils.java 2016-08-25 11:29:04.218108300 +0800
@@ -29,15 +29,10 @@
package sun.security.util;
-import jdk.internal.misc.Unsafe;
-
import java.io.EOFException;
-import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
-import java.security.Permission;
import java.util.Arrays;
-import java.util.function.Function;
public class IOUtils {
diff -u new/src/java.base/share/classes/sun/security/util/FilePermCompat.java new/src/java.base/share/classes/sun/security/util/FilePermCompat.java
--- new/src/java.base/share/classes/sun/security/util/FilePermCompat.java 2016-08-25 11:29:45.937089100 +0800
+++ new/src/java.base/share/classes/sun/security/util/FilePermCompat.java 2016-09-01 22:22:15.945112900 +0800
@@ -25,26 +25,25 @@
package sun.security.util;
-import jdk.internal.misc.Unsafe;
import sun.security.action.GetPropertyAction;
import java.io.FilePermission;
import java.security.Permission;
-import java.util.function.Function;
+import jdk.internal.misc.SharedSecrets;
/**
* Take care of FilePermission compatibility after JDK-8164705.
*/
public class FilePermCompat {
/**
- * New behavior? Default "new".
+ * New behavior? Keep compatibility? Both default true.
*/
public static final boolean nb;
public static final boolean compat;
static {
String flag = GetPropertyAction.privilegedGetProperty(
- "jdk.filepermission.canonicalize", "compat");
+ "jdk.io.permissionsUseCanonicalPath", "false");
switch (flag) {
case "true":
nb = false;
@@ -52,51 +51,26 @@
break;
case "false":
nb = true;
- compat = false;
- break;
- case "compat":
- nb = true;
compat = true;
break;
default:
throw new RuntimeException(
- "Invalid jdk.filepermission.canonicalize: " + flag);
+ "Invalid jdk.io.permissionsUseCanonicalPath: " + flag);
}
}
- /**
- * These fields will be initialized by FilePermission in a static
- * block, so that they can access its internals.
- */
- public static Function<FilePermission,FilePermission>
- newPermPlusAltPathFunction, newPermUsingAltPathFunction;
-
- /**
- * Returns a new FilePermission plus an alternative path.
- *
- * @param input the input
- * @return the new FilePermission plus the alt path (as npath2)
- * or the input itself if no alt path is available.
- */
public static Permission newPermPlusAltPath(Permission input) {
if (compat && input instanceof FilePermission) {
- Unsafe.getUnsafe().ensureClassInitialized(FilePermission.class);
- return newPermPlusAltPathFunction.apply((FilePermission) input);
+ return SharedSecrets.getJavaIOFilePermissionAccess()
+ .newPermPlusAltPath((FilePermission) input);
}
return input;
}
- /**
- * Returns a new FilePermission using an alternative path.
- *
- * @param input the input
- * @return the new FilePermission using the alt path (as npath)
- * or null if no alt path is available
- */
public static Permission newPermUsingAltPath(Permission input) {
if (input instanceof FilePermission) {
- Unsafe.getUnsafe().ensureClassInitialized(FilePermission.class);
- return newPermUsingAltPathFunction.apply((FilePermission) input);
+ return SharedSecrets.getJavaIOFilePermissionAccess()
+ .newPermUsingAltPath((FilePermission) input);
}
return null;
}
reverted:
--- new/test/java/io/FilePermission/samepath.sh 2016-08-25 11:29:58.095274900 +0800
+++ /dev/null 2016-08-25 11:29:59.000000000 +0800
@@ -1,139 +0,0 @@
-#
-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 8164705
-# @summary Still able to read file on the same path
-#
-# @run shell samepath.sh
-
-if [ "${TESTSRC}" = "" ] ; then
- TESTSRC="."
-fi
-
-if [ "${TESTJAVA}" = "" ] ; then
- JAVA_CMD=`which java`
- TESTJAVA=`dirname $JAVA_CMD`/..
-fi
-
-JAVA="$TESTJAVA/bin/java -Djava.security.manager"
-JAVAC=$TESTJAVA/bin/javac
-JAR=$TESTJAVA/bin/jar
-
-if [ -f $TESTJAVA/bin/jlink ]; then
- JAKE=true
-else
- JAKE=false
-fi
-
-cat > App.java <<EOF
-package sp;
-import java.io.InputStream;
-import java.io.FileInputStream;
-public class App {
- public static void main(String[] args) throws Exception {
- boolean f = true;
- StringBuilder sb = new StringBuilder();
- String expected = null;
- for (String s: args) {
- if (expected == null) {
- expected = s;
- } else if (s.equals("-")) {
- f = false;
- } else if (f) {
- try (InputStream is = new FileInputStream(s)) {
- is.readAllBytes();
- sb.append('+');
- } catch (SecurityException se) {
- System.out.println(se);
- sb.append('S');
- } catch (Exception e) {
- System.out.println(e);
- sb.append('-');
- }
- } else {
- try (InputStream is = App.class.getResourceAsStream(s)) {
- is.readAllBytes();
- sb.append('+');
- } catch (NullPointerException npe) {
- System.out.println(npe);
- sb.append('0');
- } catch (Exception e) {
- System.out.println(e);
- sb.append('-');
- }
- }
- }
- if (!sb.toString().equals(expected)) {
- throw new Exception("Expected " + expected + ", actually " + sb);
- } else {
- System.out.println("OK");
- }
- }
-}
-EOF
-
-cat > module-info.java <<EOF
-module sp {
- exports sp;
-}
-EOF
-
-mkdir classes oldjar newjar
-mkdir -p m/sp
-
-$JAVAC -d classes App.java || exit 1
-rm classes/module-info.class 2> /dev/null
-echo base > classes/base
-echo child > classes/sp/child
-$JAR cvf oldjar/old.jar -C classes .
-
-if [ $JAKE = true ]; then
- $JAVAC -d m/sp App.java module-info.java || exit 1
- echo base > m/sp/base
- echo child > m/sp/sp/child
- $JAR cvf newjar/new.jar -C m/sp .
-fi
-
-$JAVA -cp classes sp.App S+++++ x classes/base classes/sp/child - child /base ../base || exit 1
-$JAVA -cp oldjar/old.jar sp.App S++0 classes/base - child /base ../base || exit 11
-if [ $JAKE = true ]; then
- $JAVA -mp m -m sp/sp.App S+++++ m/sp m/sp/base m/sp/sp/child - child /base ../base || exit 21
- $JAVA -mp newjar -m sp/sp.App SSS++0 m/sp m/sp/base m/sp/sp/child - child /base ../base || exit 31
-fi
-
-# For Windows, we also check viewing from another drive. Even if there is no
-# ALT_DRIVE: we can also check if C:x and x are the same file.
-
-# We do not support so much.
-if [ -f /usr/bin/cygpath---XXX ]; then
- [ -d /cygdrive/d ] && ALT_DRIVE=D || ALT_DRIVE=C
- JAVA=`cygpath -m $TESTJAVA`"/bin/java -Djava.security.manager"
- cmd /c "$ALT_DRIVE: && $JAVA -cp C:classes sp.App S+++++ C:x C:classes/base C:classes/sp/child - child /base ../base" || exit 41
- cmd /c "$ALT_DRIVE: && $JAVA -cp C:oldjar/old.jar sp.App S++0 C:classes/base - child /base ../base" || exit 51
- if [ $JAKE = true ]; then
- cmd /c "$ALT_DRIVE: && $JAVA -mp C:m -m sp/sp.App S+++++ C:m/sp C:m/sp/base C:m/sp/sp/child - child /base ../base" || exit 61
- cmd /c "$ALT_DRIVE: && $JAVA -mp C:newjar -m sp/sp.App SSS++0 C:m/sp C:m/sp/base C:m/sp/sp/child - child /base ../base" || exit 71
- fi
-fi
-echo Done
diff -u new/test/sun/security/util/FilePermCompat/Flag.java new/test/sun/security/util/FilePermCompat/Flag.java
--- new/test/sun/security/util/FilePermCompat/Flag.java 2016-08-25 11:30:10.694687200 +0800
+++ new/test/sun/security/util/FilePermCompat/Flag.java 2016-09-01 22:22:50.292834600 +0800
@@ -27,9 +27,8 @@
* @summary check jdk.filepermission.canonicalize
* @library /java/security/testlibrary/
* @modules java.base/jdk.internal.misc
- * @run main/othervm -Djdk.filepermission.canonicalize=true Flag truetrue
- * @run main/othervm -Djdk.filepermission.canonicalize=false Flag falsefalse
- * @run main/othervm -Djdk.filepermission.canonicalize=compat Flag falsetrue
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=true Flag truetrue
+ * @run main/othervm -Djdk.io.permissionsUseCanonicalPath=false Flag falsetrue
* @run main/othervm Flag falsetrue
*/
only in patch2:
unchanged:
--- old/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java 2016-09-01 22:21:18.260490500 +0800
+++ new/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java 2016-09-01 22:21:17.294984800 +0800
@@ -29,6 +29,7 @@
import java.util.jar.JarFile;
import java.io.Console;
import java.io.FileDescriptor;
+import java.io.FilePermission;
import java.io.ObjectInputStream;
import java.io.RandomAccessFile;
import java.security.ProtectionDomain;
@@ -58,6 +59,7 @@
private static JavaNetSocketAccess javaNetSocketAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
+ private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
private static JavaSecurityAccess javaSecurityAccess;
private static JavaUtilZipFileAccess javaUtilZipFileAccess;
@@ -201,6 +203,17 @@
javaIOFileDescriptorAccess = jiofda;
}
+ public static JavaIOFilePermissionAccess getJavaIOFilePermissionAccess() {
+ if (javaIOFilePermissionAccess == null)
+ unsafe.ensureClassInitialized(FilePermission.class);
+
+ return javaIOFilePermissionAccess;
+ }
+
+ public static void setJavaIOFilePermissionAccess(JavaIOFilePermissionAccess jiofpa) {
+ javaIOFilePermissionAccess = jiofpa;
+ }
+
public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() {
if (javaIOFileDescriptorAccess == null)
unsafe.ensureClassInitialized(FileDescriptor.class);
only in patch2:
unchanged:
--- /dev/null 2016-09-01 22:22:11.000000000 +0800
+++ new/src/java.base/share/classes/jdk/internal/misc/JavaIOFilePermissionAccess.java 2016-09-01 22:22:09.978471900 +0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.misc;
+
+import java.io.FilePermission;
+
+public interface JavaIOFilePermissionAccess {
+
+ /**
+ * Returns a new FilePermission plus an alternative path.
+ *
+ * @param input the input
+ * @return the new FilePermission plus the alt path (as npath2)
+ * or the input itself if no alt path is available.
+ */
+ FilePermission newPermPlusAltPath(FilePermission input);
+
+ /**
+ * Returns a new FilePermission using an alternative path.
+ *
+ * @param input the input
+ * @return the new FilePermission using the alt path (as npath)
+ * or null if no alt path is available
+ */
+ FilePermission newPermUsingAltPath(FilePermission input);
+}
only in patch2:
unchanged:
--- /dev/null 2016-09-01 22:22:28.000000000 +0800
+++ new/test/java/io/FilePermission/ReadFileOnPath.java 2016-09-01 22:22:27.359520300 +0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8164705
+ * @library /lib/testlibrary /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @run main ReadFileOnPath
+ * @summary Still able to read file on the same path
+ */
+
+import jdk.test.lib.process.ProcessTools;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ReadFileOnPath {
+
+ private static final Path SRC_DIR = Paths.get(System.getProperty("test.src"));
+ private static final Path HERE_DIR = Paths.get(".");
+ private static final Path MODS_DIR = Paths.get("modules");
+
+ public static void main(String args[]) throws Exception {
+ CompilerUtils.compile(SRC_DIR.resolve("m"), MODS_DIR.resolve("m"));
+ Files.write(MODS_DIR.resolve("m/base"), "base".getBytes());
+ Files.write(MODS_DIR.resolve("m/p/child"), "child".getBytes());
+ JarUtils.createJarFile(HERE_DIR.resolve("old.jar"),
+ MODS_DIR.resolve("m"),
+ "base", "p/App.class", "p/child");
+ JarUtils.createJarFile(HERE_DIR.resolve("new.jar"),
+ MODS_DIR.resolve("m"),
+ "module-info.class", "base", "p/App.class", "p/child");
+
+ // exploded module
+ test("--module-path", "modules", "-m", "m/p.App", "SS+++++");
+
+ // module in jar
+ test("--module-path", "new.jar", "-m", "m/p.App", "SSSS++0");
+
+ // exploded classpath
+ test("-cp", "modules/m", "p.App", "SS+++++");
+
+ // classpath in jar
+ test("-cp", "old.jar", "p.App", "SSSS++0");
+ }
+
+ static void test(String... args) throws Exception {
+ List<String> cmds = new ArrayList<>();
+ cmds.add("-Djava.security.manager");
+ cmds.addAll(Arrays.asList(args));
+ cmds.addAll(List.of(
+ "x", "modules/m", "modules/m/base", "modules/m/p/child",
+ "-", "child", "/base", "../base"));
+ ProcessTools.executeTestJvm(cmds.toArray(new String[cmds.size()]))
+ .shouldHaveExitValue(0);
+ }
+}
only in patch2:
unchanged:
--- /dev/null 2016-09-01 22:22:34.000000000 +0800
+++ new/test/java/io/FilePermission/m/module-info.java 2016-09-01 22:22:33.180356500 +0800
@@ -0,0 +1,3 @@
+module m {
+ exports p;
+}
only in patch2:
unchanged:
--- /dev/null 2016-09-01 22:22:40.000000000 +0800
+++ new/test/java/io/FilePermission/m/p/App.java 2016-09-01 22:22:38.900011600 +0800
@@ -0,0 +1,44 @@
+package p;
+import java.io.InputStream;
+import java.io.FileInputStream;
+public class App {
+ public static void main(String[] args) throws Exception {
+ boolean f = true;
+ StringBuilder sb = new StringBuilder();
+ String expected = null;
+ for (String s: args) {
+ if (expected == null) {
+ expected = s;
+ } else if (s.equals("-")) {
+ f = false;
+ } else if (f) {
+ try (InputStream is = new FileInputStream(s)) {
+ is.readAllBytes();
+ sb.append('+');
+ } catch (SecurityException se) {
+ System.out.println(se);
+ sb.append('S');
+ } catch (Exception e) {
+ System.out.println(e);
+ sb.append('-');
+ }
+ } else {
+ try (InputStream is = App.class.getResourceAsStream(s)) {
+ is.readAllBytes();
+ sb.append('+');
+ } catch (NullPointerException npe) {
+ System.out.println(npe);
+ sb.append('0');
+ } catch (Exception e) {
+ System.out.println(e);
+ sb.append('-');
+ }
+ }
+ }
+ if (!sb.toString().equals(expected)) {
+ throw new Exception("Expected " + expected + ", actually " + sb);
+ } else {
+ System.out.println("OK");
+ }
+ }
+}