Skip to content
Permalink
Browse files

8249080: Reduce MemberName class dependency on MethodHandles

Reviewed-by: mchung
  • Loading branch information
Bob Vandette
Bob Vandette committed Jul 8, 2020
1 parent f4f0940 commit 65b23ca67a2ca602127d5cbed1ff0611032a47f5
Showing with 52 additions and 13 deletions.
  1. +52 −13 src/java.base/share/classes/java/lang/invoke/MethodHandles.java
@@ -2614,15 +2614,36 @@ public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuc
throw new IllegalArgumentException(targetClass + " is an array class");

if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
throw new MemberName(targetClass).makeAccessException("access violation", this);
throw makeAccessException(targetClass);
}
checkSecurityManager(targetClass, null);
checkSecurityManager(targetClass);

// ensure class initialization
Unsafe.getUnsafe().ensureClassInitialized(targetClass);
return targetClass;
}

/*
* Returns IllegalAccessException due to access violation to the given targetClass.
*
* This method is called by {@link Lookup#accessClass} and {@link Lookup#ensureInitialized}
* which verifies access to a class rather a member.
*/
private IllegalAccessException makeAccessException(Class<?> targetClass) {
String message = "access violation: "+ targetClass;
if (this == MethodHandles.publicLookup()) {
message += ", from public Lookup";
} else {
Module m = lookupClass().getModule();
message += ", from " + lookupClass() + " (" + m + ")";
if (prevLookupClass != null) {
message += ", previous lookup " +
prevLookupClass.getName() + " (" + prevLookupClass.getModule() + ")";
}
}
return new IllegalAccessException(message);
}

/**
* Determines if a class can be accessed from the lookup context defined by
* this {@code Lookup} object. The static initializer of the class is not run.
@@ -2693,9 +2714,9 @@ public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuc
*/
public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
throw new MemberName(targetClass).makeAccessException("access violation", this);
throw makeAccessException(targetClass);
}
checkSecurityManager(targetClass, null);
checkSecurityManager(targetClass);
return targetClass;
}

@@ -3514,11 +3535,37 @@ public boolean hasFullPrivilegeAccess() {
}

/**
* Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Perform steps 1 and 2b <a href="MethodHandles.Lookup.html#secmgr">access checks</a>
* for ensureInitialzed, findClass or accessClass.
*/
void checkSecurityManager(Class<?> refc) {
if (allowedModes == TRUSTED) return;

SecurityManager smgr = System.getSecurityManager();
if (smgr == null) return;

// Step 1:
boolean fullPowerLookup = hasFullPrivilegeAccess();
if (!fullPowerLookup ||
!VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
ReflectUtil.checkPackageAccess(refc);
}

// Step 2b:
if (!fullPowerLookup) {
smgr.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}

/**
* Perform steps 1, 2a and 3 <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Determines a trustable caller class to compare with refc, the symbolic reference class.
* If this lookup object has full privilege access, then the caller class is the lookupClass.
*/
void checkSecurityManager(Class<?> refc, MemberName m) {
Objects.requireNonNull(refc);
Objects.requireNonNull(m);

if (allowedModes == TRUSTED) return;

SecurityManager smgr = System.getSecurityManager();
@@ -3531,14 +3578,6 @@ void checkSecurityManager(Class<?> refc, MemberName m) {
ReflectUtil.checkPackageAccess(refc);
}

if (m == null) { // findClass or accessClass
// Step 2b:
if (!fullPowerLookup) {
smgr.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
return;
}

// Step 2a:
if (m.isPublic()) return;
if (!fullPowerLookup) {

0 comments on commit 65b23ca

Please sign in to comment.
You can’t perform that action at this time.