From 7efe9168bea3caa86922efe3e172e14868a32edd Mon Sep 17 00:00:00 2001 From: Jason Feng Date: Mon, 16 Jul 2018 15:39:21 -0400 Subject: [PATCH] Skip parameter access check for reflect objects Introduced a boolean flag to indicate that MethodType parameters should be skipped for access checking; Skip parameter access check for reflect objects; Adopted this extra parameter in other APIs. Signed-off-by: Jason Feng --- .../lang/invoke/MethodHandleInfoImpl.java | 2 +- .../java/lang/invoke/MethodHandles.java | 47 ++++++++++--------- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfoImpl.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfoImpl.java index 58e1686e4e7..ea64f733f83 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfoImpl.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandleInfoImpl.java @@ -93,7 +93,7 @@ public T reflectAs(Class expected, MethodHandles.Lookup lo throw new NullPointerException(); } try { - lookup.checkAccess(mh); + lookup.checkAccess(mh, false); } catch (IllegalAccessException e) { /*[MSG "K0583", "The Member is not accessible to the Lookup object"]*/ IllegalArgumentException x = new IllegalArgumentException(com.ibm.oti.util.Msg.getString("K0583")); //$NON-NLS-1$ diff --git a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 176f0e58399..a18fcd96f43 100644 --- a/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -257,7 +257,7 @@ public MethodHandle bind(Object receiver, String methodName, MethodType type) th handle = handle.asFixedArity(); // remove unnecessary varargsCollector from the middle of the MH chain. handle = convertToVarargsIfRequired(handle.bindTo(receiver)); } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), receiverClass, handle.getModifiers()); handle = SecurityFrameInjector.wrapHandleWithInjectedSecurityFrameIfRequired(this, handle); @@ -337,7 +337,7 @@ private static boolean isSamePackage(Class a, Class b){ return false; } - void checkAccess(MethodHandle handle) throws IllegalAccessException { + void checkAccess(MethodHandle handle, boolean skipAccessCheckPara) throws IllegalAccessException { if (INTERNAL_PRIVILEGED == accessMode) { // Full access for use by MH implementation. return; @@ -347,11 +347,11 @@ void checkAccess(MethodHandle handle) throws IllegalAccessException { throw new IllegalAccessException(this.toString()); } - checkAccess(handle.getDefc(), handle.getMethodName(), handle.getModifiers(), handle); + checkAccess(handle.getDefc(), handle.getMethodName(), handle.getModifiers(), handle, skipAccessCheckPara); } /*[IF Sidecar19-SE]*/ - void checkAccess(VarHandle handle) throws IllegalAccessException { + void checkAccess(VarHandle handle, boolean reflectiveAccess) throws IllegalAccessException { if (INTERNAL_PRIVILEGED == accessMode) { // Full access for use by MH implementation. return; @@ -361,7 +361,7 @@ void checkAccess(VarHandle handle) throws IllegalAccessException { throw new IllegalAccessException(this.toString()); } - checkAccess(handle.getDefiningClass(), handle.getFieldName(), handle.getModifiers(), null); + checkAccess(handle.getDefiningClass(), handle.getFieldName(), handle.getModifiers(), null, reflectiveAccess); } void checkAccess(Class clazz) throws IllegalAccessException { @@ -389,14 +389,15 @@ void checkAccess(Class clazz) throws IllegalAccessException { * The object is always {@link MethodHandle} in the current implementation, so in order * to avoid extra type checking, the parameter is {@link MethodHandle}. If we need to * handle {@link VarHandle} in the future, the type can be {@link Object}. + * @param skipAccessCheckPara skip access check for MethodType parameters * @throws IllegalAccessException If the member is not accessible. * @throws IllegalAccessError If a handle argument or return type is not accessible. */ - private void checkAccess(Class targetClass, String name, int memberModifiers, MethodHandle handle) throws IllegalAccessException { + private void checkAccess(Class targetClass, String name, int memberModifiers, MethodHandle handle, boolean skipAccessCheckPara) throws IllegalAccessException { checkClassAccess(targetClass); /*[IF Sidecar19-SE]*/ - if (null != handle) { + if (null != handle && !skipAccessCheckPara) { MethodType type = handle.type(); Module accessModule = accessClass.getModule(); @@ -580,7 +581,7 @@ public MethodHandle findSpecial(Class clazz, String methodName, MethodType ty /*[MSG "K0586", "Lookup class ({0}) must be the same as or subclass of the current class ({1})"]*/ throw new IllegalAccessException(com.ibm.oti.util.Msg.getString("K0586", accessClass, handleDefc)); //$NON-NLS-1$ } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handleDefc, clazz, handle.getModifiers()); handle = SecurityFrameInjector.wrapHandleWithInjectedSecurityFrameIfRequired(this, handle); } catch (DefaultMethodConflictException e) { @@ -641,7 +642,7 @@ public MethodHandle findStatic(Class clazz, String methodName, MethodType typ handle = new DirectHandle(clazz, methodName, type, MethodHandle.KIND_STATIC, null); handle = HandleCache.putMethodInPerClassCache(cache, methodName, type, convertToVarargsIfRequired(handle)); } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), clazz, handle.getModifiers()); /* Static check is performed by native code */ handle = SecurityFrameInjector.wrapHandleWithInjectedSecurityFrameIfRequired(this, handle); @@ -717,7 +718,7 @@ public MethodHandle findVirtual(Class clazz, String methodName, MethodType ty HandleCache.putMethodInPerClassCache(cache, methodName, type, handle); } handle = restrictReceiver(handle); - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), clazz, handle.getModifiers()); handle = SecurityFrameInjector.wrapHandleWithInjectedSecurityFrameIfRequired(this, handle); return handle; @@ -924,7 +925,7 @@ public MethodHandle findGetter(Class clazz, String fieldName, Class fieldT handle = new FieldGetterHandle(clazz, fieldName, fieldType, accessClass); HandleCache.putFieldInPerClassCache(cache, fieldName, fieldType, handle); } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), clazz, handle.getModifiers()); return handle; } @@ -951,7 +952,7 @@ public MethodHandle findStaticGetter(Class clazz, String fieldName, Class handle = new StaticFieldGetterHandle(clazz, fieldName, fieldType, accessClass); HandleCache.putFieldInPerClassCache(cache, fieldName, fieldType, handle); } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), clazz, handle.getModifiers()); return handle; } @@ -986,7 +987,7 @@ public MethodHandle findSetter(Class clazz, String fieldName, Class fieldT /*[MSG "K05cf", "illegal setter on final field"]*/ throw new IllegalAccessException(Msg.getString("K05cf")); //$NON-NLS-1$ } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), clazz, handle.getModifiers()); return handle; } @@ -1021,7 +1022,7 @@ public MethodHandle findStaticSetter(Class clazz, String fieldName, Class /*[MSG "K05cf", "illegal setter on final field"]*/ throw new IllegalAccessException(Msg.getString("K05cf")); //$NON-NLS-1$ } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), clazz, handle.getModifiers()); return handle; } @@ -1235,7 +1236,7 @@ public MethodHandle unreflect(Method method) throws IllegalAccessException{ if (!method.isAccessible()) { handle = restrictReceiver(handle); - checkAccess(handle); + checkAccess(handle, true); } handle = SecurityFrameInjector.wrapHandleWithInjectedSecurityFrameIfRequired(this, handle); @@ -1319,7 +1320,7 @@ public MethodHandle unreflectConstructor(Constructor method) throws IllegalAc } if (!method.isAccessible()) { - checkAccess(handle); + checkAccess(handle, true); } return handle; @@ -1350,7 +1351,7 @@ public MethodHandle findConstructor(Class declaringClass, MethodType type) th } handle = HandleCache.putMethodInPerClassCache(cache, "", type, convertToVarargsIfRequired(handle)); //$NON-NLS-1$ } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(handle.getDefc(), declaringClass, handle.getModifiers()); return handle; } @@ -1382,7 +1383,7 @@ public MethodHandle unreflectSpecial(Method method, Class specialToken) throw } if (!method.isAccessible()) { - checkAccess(handle); + checkAccess(handle, true); } handle = SecurityFrameInjector.wrapHandleWithInjectedSecurityFrameIfRequired(this, handle); @@ -1427,7 +1428,7 @@ public MethodHandle unreflectGetter(Field field) throws IllegalAccessException { HandleCache.putFieldInPerClassCache(cache, fieldName, fieldType, handle); } if (!field.isAccessible()) { - checkAccess(handle); + checkAccess(handle, true); } return handle; } @@ -1478,7 +1479,7 @@ public MethodHandle unreflectSetter(Field field) throws IllegalAccessException { } if (!field.isAccessible()) { - checkAccess(handle); + checkAccess(handle, true); } return handle; } @@ -1503,7 +1504,7 @@ public MethodHandleInfo revealDirect(MethodHandle target) throws IllegalArgument } } try { - checkAccess(target); + checkAccess(target, false); checkSecurity(target.getDefc(), target.getReferenceClass(), target.getModifiers()); } catch (IllegalAccessException e) { throw new IllegalArgumentException(e); @@ -1674,7 +1675,7 @@ private VarHandle findVarHandleCommon(Class definingClass, String name, Class } else { handle = new InstanceFieldVarHandle(definingClass, name, type, this.accessClass); } - checkAccess(handle); + checkAccess(handle, false); checkSecurity(definingClass, definingClass, handle.getModifiers()); return handle; } catch (NoSuchFieldError e) { @@ -1710,7 +1711,7 @@ public VarHandle unreflectVarHandle(Field field) throws IllegalAccessException { handle = new InstanceFieldVarHandle(field, field.getDeclaringClass(), field.getType()); } - checkAccess(handle); + checkAccess(handle, true); checkSecurity(handle.getDefiningClass(), handle.getDefiningClass(), handle.modifiers); return handle;