Skip to content

Commit

Permalink
Selectively enforce lookup class package check
Browse files Browse the repository at this point in the history
Only following APIs are subject to lookup class package check (matching
RI behaviours):

MethodHandles.Lookup.in​(Class<?> lookupClass)
MethodHandles.Lookup.dropLookupMode​(int modeToDrop)
MethodHandles.Lookup.privateLookupIn​(Class<?> targetClass,
MethodHandles.Lookup caller)
The change only applies to JDK15. The package check stays same for
pre-JDK15 levels.

Signed-off-by: Jason Feng <fengj@ca.ibm.com>
  • Loading branch information
JasonFengJ9 committed Aug 7, 2020
1 parent 0346887 commit 514b23b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
38 changes: 27 additions & 11 deletions jcl/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Original file line number Diff line number Diff line change
Expand Up @@ -215,24 +215,40 @@ static final public class Lookup {
accessMode = lookupMode;
}

Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int lookupMode) {
this(lookupClass, prevLookupClass, lookupMode, true);
/* For Java 15, the default is not to check for the "java.lang.invoke" package.
* For earlier releases, these lookups are illegal
*/
private static boolean lookupJLIPackageCheckDefault() {
/*[IF Java15]
return false;
/*[ELSE] Java15*/
return true;
/*[ENDIF] Java15*/
}

Lookup(Class<?> lookupClass, int lookupMode, boolean doCheck) {
this(lookupClass, null, lookupMode, doCheck);
Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int lookupMode) {
this(lookupClass, prevLookupClass, lookupMode, lookupJLIPackageCheckDefault());
}

Lookup(Class<?> lookupClass, int lookupMode) {
this(lookupClass, lookupMode, true);
this(lookupClass, null, lookupMode, lookupJLIPackageCheckDefault());
}

Lookup(Class<?> lookupClass) {
this(lookupClass, FULL_ACCESS_MASK, true);
this(lookupClass, null, FULL_ACCESS_MASK, lookupJLIPackageCheckDefault());
}

/* Note:
* The constructor Lookup(Class<?> lookupClass) above performs package check by default.
* Following constructor is used when there is no need for such check,
* i.e., incoming performSecurityCheck is expected to be false here.
* JDK15+ expects only following three APIs invoking Lookup constructors to do such package check (matching RI behaviors):
* MethodHandles.Lookup.in(Class<?> lookupClass)
* MethodHandles.Lookup.dropLookupMode(Class<?> lookupClass)
* MethodHandles.Lookup.privateLookupIn(Class<?> targetClass, MethodHandles.Lookup caller)
*/
Lookup(Class<?> lookupClass, boolean performSecurityCheck) {
this(lookupClass, FULL_ACCESS_MASK, performSecurityCheck);
this(lookupClass, null, FULL_ACCESS_MASK, performSecurityCheck);
}

/**
Expand Down Expand Up @@ -1426,7 +1442,7 @@ public MethodHandles.Lookup in(Class<?> lookupClass) {
newPrevAccessClass = null;
}

return new Lookup(lookupClass, newPrevAccessClass, newAccessMode);
return new Lookup(lookupClass, newPrevAccessClass, newAccessMode, true);
/*[ELSE]*/
return new Lookup(lookupClass, newAccessMode);
/*[ENDIF] Java14*/
Expand Down Expand Up @@ -2214,7 +2230,7 @@ public MethodHandles.Lookup dropLookupMode(int dropMode) {
newPrevAccessClass = null;
}

return new Lookup(accessClass, newPrevAccessClass, newAccessMode);
return new Lookup(accessClass, newPrevAccessClass, newAccessMode, true);
/*[ELSE]*/
return new Lookup(accessClass, newAccessMode);
/*[ENDIF] Java14*/
Expand Down Expand Up @@ -2483,9 +2499,9 @@ public static MethodHandles.Lookup privateLookupIn(Class<?> targetClass, MethodH

/*[IF Java14]*/
if (Objects.equals(targetClassModule, accessClassModule)) {
return new Lookup(targetClass, null, callerLookupMode);
return new Lookup(targetClass, null, callerLookupMode, true);
} else {
return new Lookup(targetClass, callerLookup.lookupClass(), (callerLookupMode & ~Lookup.MODULE));
return new Lookup(targetClass, callerLookup.lookupClass(), (callerLookupMode & ~Lookup.MODULE), true);
}
/*[ELSE]*/
return new Lookup(targetClass);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.openj9.test.java.lang.invoke;

/*******************************************************************************
* Copyright (c) 1998, 2018 IBM Corp. and others
* Copyright (c) 1998, 2020 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 @@ -33,10 +33,10 @@
import java.lang.reflect.*;
import java.security.AccessControlException;
import org.openj9.test.java.lang.invoke.helpers.*;
import org.openj9.test.util.VersionCheck;
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;


public class Test_MethodHandleInfo {
@SuppressWarnings("unused")
private String privateField = "privateField";
Expand Down Expand Up @@ -686,6 +686,11 @@ public void test_RevealDirect_TargetVarargsHandle() throws Throwable {
*/
@Test(groups = { "level.sanity" })
public void test_RevealDirect_Security() throws Throwable {
if (VersionCheck.major() >= 15) {
/* This test doesn't apply to JDK15+ after removing package check for MethodHandles.Lookup() constructors exception three APIs */
return;
}

final String lookup = "org.openj9.test.java.lang.invoke.Helper_MethodHandleInfo";
final String methodHandle = "org.openj9.test.java.lang.invoke.helpers.Helper_MethodHandleInfoOtherPackagePublic";

Expand Down

0 comments on commit 514b23b

Please sign in to comment.