Skip to content

Commit

Permalink
8249080: Reduce MemberName class dependency on MethodHandles
Browse files Browse the repository at this point in the history
Reviewed-by: mchung
  • Loading branch information
Bob Vandette committed Jul 8, 2020
1 parent f4f0940 commit 65b23ca
Showing 1 changed file with 52 additions and 13 deletions.
65 changes: 52 additions & 13 deletions src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Expand Up @@ -2614,15 +2614,36 @@ public Class<?> ensureInitialized(Class<?> targetClass) throws IllegalAccessExce
throw new IllegalArgumentException(targetClass + " is an array class"); throw new IllegalArgumentException(targetClass + " is an array class");


if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) { 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 // ensure class initialization
Unsafe.getUnsafe().ensureClassInitialized(targetClass); Unsafe.getUnsafe().ensureClassInitialized(targetClass);
return 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 * 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. * this {@code Lookup} object. The static initializer of the class is not run.
Expand Down Expand Up @@ -2693,9 +2714,9 @@ public Class<?> ensureInitialized(Class<?> targetClass) throws IllegalAccessExce
*/ */
public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException { public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) { 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; return targetClass;
} }


Expand Down Expand Up @@ -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. * 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. * If this lookup object has full privilege access, then the caller class is the lookupClass.
*/ */
void checkSecurityManager(Class<?> refc, MemberName m) { void checkSecurityManager(Class<?> refc, MemberName m) {
Objects.requireNonNull(refc);
Objects.requireNonNull(m);

if (allowedModes == TRUSTED) return; if (allowedModes == TRUSTED) return;


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


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

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

0 comments on commit 65b23ca

Please sign in to comment.