Skip to content

Commit

Permalink
Merge pull request #3592 from pdbain-ibm/checkaccess
Browse files Browse the repository at this point in the history
Fix checking method handle access
  • Loading branch information
DanHeidinga committed Jan 15, 2019
2 parents a577adf + e628544 commit 9578b8e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*[INCLUDE-IF]*/
#
# Copyright (c) 1998, 2018 IBM Corp. and others
# Copyright (c) 1998, 2019 IBM Corp. and others
#
# This program and the accompanying materials are made available under
# the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -1038,6 +1038,7 @@ K0584="The target is not a direct handle"

K0585="{0} could not access {1} - private access required"
K0586="Lookup class ({0}) must be the same as or subclass of the current class ({1})"
K0587= '{0}' no access to: '{1}'
K0588="Illegal Lookup object - originated from java.lang.invoke: {0}"
K0589="Caller-sensitive method cannot be looked up using a restricted lookup object"
K0590="Can't unreflect @SignaturePolymorphic method: {0}"
Expand Down
40 changes: 27 additions & 13 deletions jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,12 @@ void checkAccess(MethodHandle handle, boolean skipAccessCheckPara) throws Illega
throw new IllegalAccessException(this.toString());
}

checkAccess(handle.getDefc(), handle.getMethodName(), handle.getModifiers(), handle, skipAccessCheckPara);
/* defc (defining class) may be a superclass of the references class.
* Note that we need to check against the requested class, which may have inherited
* the method from an inaccessible class. Protected members of a subclass are accessible to
* a superclass provided they are inherited from the superclass.
*/
checkAccess(handle.getDefc(), handle.getReferenceClass(), handle.getMethodName(), handle.getModifiers(), handle, skipAccessCheckPara);
}

/*[IF Sidecar19-SE]*/
Expand All @@ -378,7 +383,8 @@ void checkAccess(VarHandle handle, boolean skipAccessCheckPara) throws IllegalAc
throw new IllegalAccessException(this.toString());
}

checkAccess(handle.getDefiningClass(), handle.getFieldName(), handle.getModifiers(), null, skipAccessCheckPara);
/* VarHandles have no reference class */
checkAccess(handle.getDefiningClass(), null, handle.getFieldName(), handle.getModifiers(), null, skipAccessCheckPara);
}

void checkAccess(Class<?> clazz) throws IllegalAccessException {
Expand All @@ -396,10 +402,12 @@ void checkAccess(Class<?> clazz) throws IllegalAccessException {
/*[ENDIF]*/

/**
* Checks whether {@link #accessClass} can access a specific member of the {@code targetClass}.
* Checks whether {@link #accessClass} can access a specific member of the {@code referenceClass}.
* Equivalent of visible.c checkVisibility();
*
* @param targetClass The {@link Class} that owns the member being accessed.
* @param definingClass The {@link Class} that defines the member being accessed.
* @param referenceClass The {@link Class} class through which the the member is accessed,
* which must be the defining class or a subtype. May be null.
* @param name The name of member being accessed.
* @param memberModifiers The modifiers of the member being accessed.
* @param handle A handle object (e.g. {@link MethodHandle} or {@link VarHandle}), if applicable.
Expand All @@ -410,8 +418,11 @@ void checkAccess(Class<?> clazz) throws IllegalAccessException {
* @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, boolean skipAccessCheckPara) throws IllegalAccessException {
checkClassAccess(targetClass);
private void checkAccess(Class<?> definingClass, Class<?> referenceClass, String name, int memberModifiers, MethodHandle handle, boolean skipAccessCheckPara) throws IllegalAccessException {
if (null == referenceClass) {
referenceClass = definingClass;
}
checkClassAccess(referenceClass);

/*[IF Sidecar19-SE]*/
if (null != handle && !skipAccessCheckPara) {
Expand All @@ -434,22 +445,22 @@ private void checkAccess(Class<?> targetClass, String name, int memberModifiers,
/* checkClassAccess already determined that we have more than "no access" (public access) */
return;
} else if (Modifier.isPrivate(memberModifiers)) {
if (Modifier.isPrivate(accessMode) && ((targetClass == accessClass)
if (Modifier.isPrivate(accessMode) && ((definingClass == accessClass)
/*[IF Java11]*/
|| targetClass.isNestmateOf(accessClass)
|| definingClass.isNestmateOf(accessClass)
/*[ENDIF] Java11*/
)) {
return;
}
} else if (Modifier.isProtected(memberModifiers)) {
/* Ensure that the accessMode is not restricted (public-only) */
if (PUBLIC != accessMode) {
if (targetClass.isArray()) {
if (definingClass.isArray()) {
/* The only methods array classes have are defined on Object and thus accessible */
return;
}

if (isSamePackage(accessClass, targetClass)) {
if (isSamePackage(accessClass, referenceClass)) {
/* Package access is enough if the classes are in the same package */
return;
}
Expand All @@ -459,7 +470,9 @@ private void checkAccess(Class<?> targetClass, String name, int memberModifiers,
* protected methods in java.lang.Object as subclasses.
*/
/*[ENDIF]*/
if (!accessClass.isInterface() && Modifier.isProtected(accessMode) && targetClass.isAssignableFrom(accessClass)) {
if (!accessClass.isInterface() && Modifier.isProtected(accessMode)
&& definingClass.isAssignableFrom(accessClass)
) {
/* Special handling for MethodHandles */
if (null != handle) {
byte kind = handle.kind;
Expand Down Expand Up @@ -497,7 +510,7 @@ private void checkAccess(Class<?> targetClass, String name, int memberModifiers,
}
} else {
/* default (package access) */
if ((PACKAGE == (accessMode & PACKAGE)) && isSamePackage(accessClass, targetClass)){
if ((PACKAGE == (accessMode & PACKAGE)) && isSamePackage(accessClass, referenceClass)){
return;
}
}
Expand All @@ -509,7 +522,8 @@ private void checkAccess(Class<?> targetClass, String name, int memberModifiers,
} else {
extraInfo = "." + name; //$NON-NLS-1$
}
String errorMessage = com.ibm.oti.util.Msg.getString("K0587", this.toString(), targetClass.getName() + extraInfo); //$NON-NLS-1$
/*[MSG "K0587", "'{0}' no access to: '{1}'"]*/
String errorMessage = com.ibm.oti.util.Msg.getString("K0587", this.toString(), definingClass.getName() + extraInfo); //$NON-NLS-1$
throw new IllegalAccessException(errorMessage);
}

Expand Down

0 comments on commit 9578b8e

Please sign in to comment.