diff options
Diffstat (limited to 'external/ikvm/openjdk/java/lang/reflect')
4 files changed, 287 insertions, 70 deletions
diff --git a/external/ikvm/openjdk/java/lang/reflect/Constructor.java b/external/ikvm/openjdk/java/lang/reflect/Constructor.java index e62e87728d..b13d30a543 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Constructor.java +++ b/external/ikvm/openjdk/java/lang/reflect/Constructor.java @@ -25,6 +25,7 @@ package java.lang.reflect; +import sun.reflect.CallerSensitive; import sun.reflect.ConstructorAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.ConstructorRepository; @@ -501,15 +502,14 @@ public final * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public T newInstance(Object ... initargs) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = Reflection.getCallerClass(2); - + Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, null, modifiers); } } diff --git a/external/ikvm/openjdk/java/lang/reflect/Field.java b/external/ikvm/openjdk/java/lang/reflect/Field.java index c796d20a1f..b2cb46b3f0 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Field.java +++ b/external/ikvm/openjdk/java/lang/reflect/Field.java @@ -25,6 +25,7 @@ package java.lang.reflect; +import sun.reflect.CallerSensitive; import sun.reflect.FieldAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.FieldRepository; @@ -34,7 +35,6 @@ import sun.reflect.generics.scope.ClassScope; import java.lang.annotation.Annotation; import java.util.Map; import sun.reflect.annotation.AnnotationParser; -import ikvm.internal.CallerID; /** @@ -365,11 +365,16 @@ class Field extends AccessibleObject implements Member { * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).get(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).get(obj); } /** @@ -394,11 +399,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public boolean getBoolean(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getBoolean(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getBoolean(obj); } /** @@ -423,11 +433,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public byte getByte(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getByte(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getByte(obj); } /** @@ -454,11 +469,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public char getChar(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getChar(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getChar(obj); } /** @@ -485,11 +505,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public short getShort(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getShort(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getShort(obj); } /** @@ -516,11 +541,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public int getInt(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getInt(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getInt(obj); } /** @@ -547,11 +577,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public long getLong(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getLong(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getLong(obj); } /** @@ -578,11 +613,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public float getFloat(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getFloat(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getFloat(obj); } /** @@ -609,11 +649,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#get */ - @ikvm.internal.HasCallerID + @CallerSensitive public double getDouble(Object obj) throws IllegalArgumentException, IllegalAccessException { - return getFieldAccessor(obj, CallerID.getCallerID()).getDouble(obj); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + return getFieldAccessor(obj).getDouble(obj); } /** @@ -682,11 +727,16 @@ class Field extends AccessibleObject implements Member { * @exception ExceptionInInitializerError if the initialization provoked * by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).set(obj, value); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).set(obj, value); } /** @@ -713,11 +763,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setBoolean(Object obj, boolean z) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setBoolean(obj, z); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setBoolean(obj, z); } /** @@ -744,11 +799,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setByte(Object obj, byte b) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setByte(obj, b); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setByte(obj, b); } /** @@ -775,11 +835,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setChar(Object obj, char c) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setChar(obj, c); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setChar(obj, c); } /** @@ -806,11 +871,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setShort(Object obj, short s) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setShort(obj, s); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setShort(obj, s); } /** @@ -837,11 +907,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setInt(Object obj, int i) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setInt(obj, i); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setInt(obj, i); } /** @@ -868,11 +943,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setLong(Object obj, long l) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setLong(obj, l); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setLong(obj, l); } /** @@ -899,11 +979,16 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setFloat(Object obj, float f) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setFloat(obj, f); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setFloat(obj, f); } /** @@ -930,21 +1015,25 @@ class Field extends AccessibleObject implements Member { * by this method fails. * @see Field#set */ - @ikvm.internal.HasCallerID + @CallerSensitive public void setDouble(Object obj, double d) throws IllegalArgumentException, IllegalAccessException { - getFieldAccessor(obj, CallerID.getCallerID()).setDouble(obj, d); + if (!override) { + if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { + checkAccess(Reflection.getCallerClass(), clazz, obj, modifiers); + } + } + getFieldAccessor(obj).setDouble(obj, d); } - // Convenience routine which performs security checks - private FieldAccessor getFieldAccessor(Object obj, CallerID callerID) + // security check is done before calling this method + private FieldAccessor getFieldAccessor(Object obj) throws IllegalAccessException { - doSecurityCheck(obj, callerID); boolean ov = override; - FieldAccessor a = (ov)? overrideFieldAccessor : fieldAccessor; - return (a != null)? a : acquireFieldAccessor(ov); + FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor; + return (a != null) ? a : acquireFieldAccessor(ov); } // NOTE that there is no synchronization used here. It is correct @@ -989,19 +1078,6 @@ class Field extends AccessibleObject implements Member { } } - // NOTE: be very careful if you change the stack depth of this - // routine. The depth of the "getCallerClass" call is hardwired so - // that the compiler can have an easier time if this gets inlined. - private void doSecurityCheck(Object obj, CallerID callerID) throws IllegalAccessException { - if (!override) { - if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = callerID.getCallerClass(); - - checkAccess(caller, clazz, obj, modifiers); - } - } - } - /* * Utility routine to paper over array type names */ diff --git a/external/ikvm/openjdk/java/lang/reflect/Method.java b/external/ikvm/openjdk/java/lang/reflect/Method.java index b1548d6bbe..dce789a4f1 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Method.java +++ b/external/ikvm/openjdk/java/lang/reflect/Method.java @@ -26,6 +26,7 @@ package java.lang.reflect; import ikvm.internal.CallerID; +import sun.reflect.CallerSensitive; import sun.reflect.MethodAccessor; import sun.reflect.Reflection; import sun.reflect.generics.repository.MethodRepository; @@ -578,15 +579,14 @@ public final * @exception ExceptionInInitializerError if the initialization * provoked by this method fails. */ - @ikvm.internal.HasCallerID + @CallerSensitive public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { - Class<?> caller = CallerID.getCallerID().getCallerClass(); - + Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers); } } diff --git a/external/ikvm/openjdk/java/lang/reflect/Proxy.java b/external/ikvm/openjdk/java/lang/reflect/Proxy.java index d4a391f738..3d9850e032 100644 --- a/external/ikvm/openjdk/java/lang/reflect/Proxy.java +++ b/external/ikvm/openjdk/java/lang/reflect/Proxy.java @@ -27,6 +27,9 @@ package java.lang.reflect; import java.lang.ref.Reference; import java.lang.ref.WeakReference; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -36,6 +39,10 @@ import java.util.Set; import java.util.List; import java.util.WeakHashMap; import sun.misc.ProxyGenerator; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; +import sun.reflect.misc.ReflectUtil; +import sun.security.util.SecurityConstants; /** * {@code Proxy} provides static methods for creating dynamic proxy @@ -265,9 +272,67 @@ public class Proxy implements java.io.Serializable { * @param h the invocation handler for this proxy instance */ protected Proxy(InvocationHandler h) { + doNewInstanceCheck(); this.h = h; } + private static class ProxyAccessHelper { + // The permission is implementation specific. + static final Permission PROXY_PERMISSION = + new ReflectPermission("proxyConstructorNewInstance"); + // These system properties are defined to provide a short-term + // workaround if customers need to disable the new security checks. + static final boolean allowNewInstance; + static final boolean allowNullLoader; + static { + allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance"); + allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader"); + } + + private static boolean getBooleanProperty(final String key) { + String s = AccessController.doPrivileged(new PrivilegedAction<String>() { + public String run() { + return System.getProperty(key); + } + }); + return Boolean.valueOf(s); + } + + static boolean needsNewInstanceCheck(Class<?> proxyClass) { + if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) { + return false; + } + + if (ReflectUtil.isNonPublicProxyClass(proxyClass)) { + for (Class<?> intf : proxyClass.getInterfaces()) { + if (!Modifier.isPublic(intf.getModifiers())) { + return true; + } + } + } + return false; + } + } + + /* + * Access check on a proxy class that implements any non-public interface. + * + * @throws SecurityException if a security manager exists, and + * the caller does not have the permission. + */ + private void doNewInstanceCheck() { + SecurityManager sm = System.getSecurityManager(); + Class<?> proxyClass = this.getClass(); + if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) { + try { + sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION); + } catch (SecurityException e) { + throw new SecurityException("Not allowed to construct a Proxy " + + "instance that implements a non-public interface", e); + } + } + } + /** * Returns the {@code java.lang.Class} object for a proxy class * given a class loader and an array of interfaces. The proxy class @@ -342,10 +407,59 @@ public class Proxy implements java.io.Serializable { * @throws NullPointerException if the {@code interfaces} array * argument or any of its elements are {@code null} */ + @CallerSensitive public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); + } + + return getProxyClass0(loader, interfaces); + } + + /* + * Check permissions required to create a Proxy class. + * + * To define a proxy class, it performs the access checks as in + * Class.forName (VM will invoke ClassLoader.checkPackageAccess): + * 1. "getClassLoader" permission check if loader == null + * 2. checkPackageAccess on the interfaces it implements + * + * To get a constructor and new instance of a proxy class, it performs + * the package access check on the interfaces it implements + * as in Class.getConstructor. + * + * If an interface is non-public, the proxy class must be defined by + * the defining loader of the interface. If the caller's class loader + * is not the same as the defining loader of the interface, the VM + * will throw IllegalAccessError when the generated proxy class is + * being defined via the defineClass0 method. + */ + private static void checkProxyAccess(Class<?> caller, + ClassLoader loader, + Class<?>... interfaces) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + ClassLoader ccl = caller.getClassLoader(); + if (loader == null && ccl != null) { + if (!ProxyAccessHelper.allowNullLoader) { + sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); + } + } + ReflectUtil.checkProxyPackageAccess(ccl, interfaces); + } + } + + /** + * Generate a proxy class. Must call the checkProxyAccess method + * to perform permission checks before calling this. + */ + private static Class<?> getProxyClass0(ClassLoader loader, + Class<?>... interfaces) { if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } @@ -497,8 +611,9 @@ public class Proxy implements java.io.Serializable { } } - if (proxyPkg == null) { // if no non-public proxy interfaces, - proxyPkg = ""; // use the unnamed package + if (proxyPkg == null) { + // if no non-public proxy interfaces, use com.sun.proxy package + proxyPkg = ReflectUtil.PROXY_PACKAGE + "."; } generate: do @@ -592,6 +707,7 @@ generate: do * if the invocation handler, {@code h}, is * {@code null} */ + @CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) @@ -601,25 +717,50 @@ generate: do throw new NullPointerException(); } + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); + } + /* * Look up or generate the designated proxy class. */ - Class<?> cl = getProxyClass(loader, interfaces); + Class<?> cl = getProxyClass0(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { - Constructor cons = cl.getConstructor(constructorParams); - return cons.newInstance(new Object[] { h }); + final Constructor<?> cons = cl.getConstructor(constructorParams); + final InvocationHandler ih = h; + if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { + // create proxy instance with doPrivilege as the proxy class may + // implement non-public interfaces that requires a special permission + return AccessController.doPrivileged(new PrivilegedAction<Object>() { + public Object run() { + return newInstance(cons, ih); + } + }); + } else { + return newInstance(cons, ih); + } } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); - } catch (IllegalAccessException e) { - throw new InternalError(e.toString()); - } catch (InstantiationException e) { + } + } + + private static Object newInstance(Constructor<?> cons, InvocationHandler h) { + try { + return cons.newInstance(new Object[] {h} ); + } catch (IllegalAccessException | InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { - throw new InternalError(e.toString()); + Throwable t = e.getCause(); + if (t instanceof RuntimeException) { + throw (RuntimeException) t; + } else { + throw new InternalError(t.toString()); + } } } |