changeset 6646:4d1f68c59366

8003881: proposed fix for potential unauthorized indirect access to lambda method, including in applet
author rfield
date Thu, 29 Nov 2012 22:24:54 -0800
parents 2f52eeca15e5
children 5b10db63e38d
files src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java src/share/classes/java/lang/invoke/LambdaMetafactory.java src/share/classes/java/lang/invoke/MagicLambdaImpl.java src/share/classes/java/lang/invoke/MethodHandleProxies.java src/share/classes/java/lang/invoke/MethodHandleProxyLambdaMetafactory.java src/share/classes/java/lang/invoke/SerializedLambda.java
diffstat 2 files changed, 31 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu Nov 29 15:14:19 2012 +0100
+++ b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java	Thu Nov 29 22:24:54 2012 -0800
@@ -25,17 +25,15 @@
 
 package java.lang.invoke;
 
-import java.io.FileOutputStream;
-import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.security.ProtectionDomain;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import jdk.internal.org.objectweb.asm.*;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
 import sun.misc.Unsafe;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 /**
  * InnerClassLambdaMetafactory
@@ -128,14 +126,26 @@
     CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException {
         final Class<?> innerClass = spinInnerClass();
         if (invokedType.parameterCount() == 0) {
-            Constructor[] ctrs = innerClass.getDeclaredConstructors();
+            final Constructor[] ctrs = AccessController.doPrivileged(
+                    new PrivilegedAction<Constructor[]>() {
+                @Override
+                public Constructor[] run() {
+                    return innerClass.getDeclaredConstructors();
+                }
+            });
             if (ctrs.length != 1) {
-                throw new ReflectiveOperationException("Expected one lambda constructor for " 
+                throw new ReflectiveOperationException("Expected one lambda constructor for "
                         + innerClass.getCanonicalName() + ", got " + ctrs.length);
             }
-            // The lambda implementing inner class constructor is private, set 
+            // The lambda implementing inner class constructor is private, set
             // it accessible (by us) before creating the constant sole instance
-            ctrs[0].setAccessible(true);
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                @Override
+                public Void run() {
+                    ctrs[0].setAccessible(true);
+                    return null;
+                }
+            });
             Object inst = ctrs[0].newInstance();
             return new ConstantCallSite(MethodHandles.constant(samBase, inst));
         } else {
@@ -197,17 +207,27 @@
 
         final byte[] classBytes = cw.toByteArray();
 
-        if (System.getProperty("debug.dump.generated") != null) {
+        /*** Uncomment to dump the generated file
             System.out.printf("Loaded: %s (%d bytes) %n", lambdaClassName, classBytes.length);
             try (FileOutputStream fos = new FileOutputStream(lambdaClassName.replace('/', '.') + ".class")) {
                 fos.write(classBytes);
             } catch (IOException ex) {
                 Logger.getLogger(InnerClassLambdaMetafactory.class.getName()).log(Level.SEVERE, null, ex);
             }
-        }
+        ***/
 
         ClassLoader loader = targetClass.getClassLoader();
-        ProtectionDomain pd = (loader == null) ? null : targetClass.getProtectionDomain();
+        ProtectionDomain pd = (loader == null)
+            ? null
+            : AccessController.doPrivileged(
+            new PrivilegedAction<ProtectionDomain>() {
+                @Override
+                public ProtectionDomain run() {
+                    return targetClass.getProtectionDomain();
+                }
+            }
+        );
+
         return (Class<? extends T>) Unsafe.getUnsafe().defineClass(lambdaClassName, classBytes, 0, classBytes.length, loader, pd);
     }
 
--- a/src/share/classes/java/lang/invoke/MethodHandleProxyLambdaMetafactory.java	Thu Nov 29 15:14:19 2012 +0100
+++ b/src/share/classes/java/lang/invoke/MethodHandleProxyLambdaMetafactory.java	Thu Nov 29 22:24:54 2012 -0800
@@ -129,4 +129,3 @@
         }
     }
 }
-