8158851: MH.publicLookup() init circularity, triggered by custom SecurityManager with String concat and -limitmods java.base
Reviewed-by: alanb, redestad, jlaskey
--- a/jdk/src/java.base/share/classes/java/lang/System.java Wed Jun 08 12:54:37 2016 +0900
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Wed Jun 08 11:14:45 2016 +0300
@@ -1942,6 +1942,10 @@
* the application classpath or modulepath.
*/
private static void initPhase3() {
+ // Initialize publicLookup early, to avoid bootstrapping circularities
+ // with security manager using java.lang.invoke infrastructure.
+ java.lang.invoke.MethodHandles.publicLookup();
+
// set security manager
String cn = System.getProperty("java.security.manager");
if (cn != null) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jun 08 12:54:37 2016 +0900
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jun 08 11:14:45 2016 +0300
@@ -2204,15 +2204,7 @@
}
}
- private static final Class<?> PUBLIC_LOOKUP_CLASS;
- static {
- PrivilegedAction<Class<?>> pa = new PrivilegedAction<Class<?>>() {
- public Class<?> run() {
- return createClass();
- }
- };
- PUBLIC_LOOKUP_CLASS = AccessController.doPrivileged(pa);
- }
+ private static final Class<?> PUBLIC_LOOKUP_CLASS = createClass();
/**
* Lookup that is trusted minimally. It can only be used to create
--- a/jdk/test/java/lang/String/concat/WithSecurityManager.java Wed Jun 08 12:54:37 2016 +0900
+++ b/jdk/test/java/lang/String/concat/WithSecurityManager.java Wed Jun 08 11:14:45 2016 +0300
@@ -26,7 +26,7 @@
/**
* @test
* @summary String concatenation fails with a custom SecurityManager that uses concatenation
- * @bug 8155090
+ * @bug 8155090 8158851
*
* @compile WithSecurityManager.java
*
@@ -37,17 +37,43 @@
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
+ *
+ * @run main/othervm -Xverify:all -limitmods java.base WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
*/
public class WithSecurityManager {
public static void main(String[] args) throws Throwable {
- SecurityManager sm = new SecurityManager() {
- @Override
- public void checkPermission(Permission perm) {
- String abc = "abc";
- String full = abc + "def";
- }
- };
- System.setSecurityManager(sm);
- ClassLoader cl = new ClassLoader() {};
+ // First time should succeed to bootstrap everything
+ {
+ SecurityManager sm = new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+ String abc = "abc";
+ String full = abc + "def";
+ }
+ };
+ System.setSecurityManager(sm);
+ ClassLoader cl = new ClassLoader() {
+ };
+ }
+
+ // Second time should succeed to run after bootstrapping
+ {
+ SecurityManager sm = new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+ String abc = "abc";
+ String full = abc + "def";
+ }
+ };
+ System.setSecurityManager(sm);
+ ClassLoader cl = new ClassLoader() {
+ };
+ }
}
}