8222895: StackOverflowError in custom security manager that relies on ClassSpecializer
authorredestad
Thu, 02 May 2019 10:38:00 +0200
changeset 54677 beca9f8524c1
parent 54676 5b6177741464
child 54678 93f09ca4a7f8
8222895: StackOverflowError in custom security manager that relies on ClassSpecializer Reviewed-by: alanb
make/jdk/src/classes/build/tools/classlist/HelloClasslist.java
src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java
test/jdk/java/lang/String/concat/WithSecurityManager.java
--- a/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java	Wed May 01 20:48:19 2019 -0400
+++ b/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java	Thu May 02 10:38:00 2019 +0200
@@ -72,6 +72,8 @@
         String SC     = String.valueOf(args.length) + "string";
         String SCS    = String.valueOf(args.length) + "string" + String.valueOf(args.length);
         String CSS    = "string" + String.valueOf(args.length) + String.valueOf(args.length);
+        String CSC    = "string" + String.valueOf(args.length) + "string";
+        String SSC    = String.valueOf(args.length) + String.valueOf(args.length) + "string";
         String CSCS   = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length);
         String SCSC   = String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string";
         String CSCSC  = "string" + String.valueOf(args.length) + "string" + String.valueOf(args.length) + "string";
--- a/src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java	Wed May 01 20:48:19 2019 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/ClassSpecializer.java	Thu May 02 10:38:00 2019 +0200
@@ -25,6 +25,7 @@
 
 package java.lang.invoke;
 
+import jdk.internal.access.SharedSecrets;
 import jdk.internal.loader.BootLoader;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.FieldVisitor;
@@ -37,6 +38,7 @@
 import java.lang.reflect.Modifier;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -575,19 +577,19 @@
 
             // load class
             InvokerBytecodeGenerator.maybeDump(classBCName(className), classFile);
-            Class<?> speciesCode;
-
-            MethodHandles.Lookup lookup = IMPL_LOOKUP.in(topClass());
-            speciesCode = AccessController.doPrivileged(new PrivilegedAction<>() {
-                @Override
-                public Class<?> run() {
-                    try {
-                        return lookup.defineClass(classFile);
-                    } catch (Exception ex) {
-                        throw newInternalError(ex);
-                    }
-                }
-            });
+            ClassLoader cl = topClass.getClassLoader();
+            ProtectionDomain pd = null;
+            if (cl != null) {
+                pd = AccessController.doPrivileged(
+                        new PrivilegedAction<>() {
+                            @Override
+                            public ProtectionDomain run() {
+                                return topClass().getProtectionDomain();
+                            }
+                        });
+            }
+            Class<?> speciesCode = SharedSecrets.getJavaLangAccess()
+                    .defineClass(cl, className, classFile, pd, "_ClassSpecializer_generateConcreteSpeciesCode");
             return speciesCode.asSubclass(topClass());
         }
 
--- a/test/jdk/java/lang/String/concat/WithSecurityManager.java	Wed May 01 20:48:19 2019 -0400
+++ b/test/jdk/java/lang/String/concat/WithSecurityManager.java	Thu May 02 10:38:00 2019 +0200
@@ -26,7 +26,7 @@
 /**
  * @test
  * @summary String concatenation fails with a custom SecurityManager that uses concatenation
- * @bug 8155090 8158851
+ * @bug 8155090 8158851 8222895
  * @requires !vm.graal.enabled
  *
  * @compile WithSecurityManager.java
@@ -55,12 +55,17 @@
                 @Override
                 public void checkPermission(Permission perm) {
                     String abc = "abc";
-                    String full = abc + "def";
+                    int ival = perm.hashCode();
+                    String full = abc + "abc";
+                    // Contorted to avoid sweeping cases where we've
+                    // pre-generated commonly used species under the rug
+                    full = "abc" + ival + "def" + abc + "def" + abc + "def" +
+                           abc + "def" + ival + "def" + abc + "def" +
+                           abc + "def" + abc + "def" + abc + "def";
                 }
             };
             System.setSecurityManager(sm);
-            ClassLoader cl = new ClassLoader() {
-            };
+            ClassLoader cl = new ClassLoader() {};
         }
 
         // Second time should succeed to run after bootstrapping
@@ -69,12 +74,19 @@
                 @Override
                 public void checkPermission(Permission perm) {
                     String abc = "abc";
-                    String full = abc + "def";
+                    int ival = perm.hashCode();
+                    String full = abc + "abc";
+                    // Contorted variant to avoid sweeping cases where we've
+                    // pre-generated commonly used species under the rug
+                    full = "abc" + ival + "def" + abc + "def" + abc + "def" +
+                            abc + "def" + ival + "def" + abc + "def" +
+                            abc + "def" + abc + "def" + abc + "def";
                 }
             };
+
+            // Provoke checkPermission invocation
             System.setSecurityManager(sm);
-            ClassLoader cl = new ClassLoader() {
-            };
+            ClassLoader cl = new ClassLoader() {};
         }
     }
 }