8139884: Use privileged blocks when working with class loaders
Reviewed-by: hannesw, mhaupt, sundar
This commit is contained in:
parent
cabd8f2f06
commit
3d0ec10abd
@ -150,15 +150,15 @@ abstract class ClassMap<T> {
|
||||
final T newV = computeValue(clazz);
|
||||
assert newV != null;
|
||||
|
||||
final ClassLoader clazzLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
final Boolean canReferenceDirectly = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public ClassLoader run() {
|
||||
return clazz.getClassLoader();
|
||||
public Boolean run() {
|
||||
return Guards.canReferenceDirectly(classLoader, clazz.getClassLoader());
|
||||
}
|
||||
}, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
|
||||
|
||||
// If allowed to strongly reference, put it in the fast map
|
||||
if(Guards.canReferenceDirectly(classLoader, clazzLoader)) {
|
||||
if(canReferenceDirectly) {
|
||||
final T oldV = map.putIfAbsent(clazz, newV);
|
||||
return oldV != null ? oldV : newV;
|
||||
}
|
||||
|
@ -85,6 +85,9 @@ package jdk.internal.dynalink.beans;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.security.AccessController;
|
||||
import java.security.Permission;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
@ -97,6 +100,8 @@ import jdk.internal.dynalink.support.TypeUtilities;
|
||||
* JLS.
|
||||
*/
|
||||
final class ClassString {
|
||||
private static final Permission GET_CLASS_LOADER_PERMISSION = new RuntimePermission("getClassLoader");
|
||||
|
||||
/**
|
||||
* An anonymous inner class used solely to represent the "type" of null values for method applicability checking.
|
||||
*/
|
||||
@ -143,12 +148,17 @@ final class ClassString {
|
||||
}
|
||||
|
||||
boolean isVisibleFrom(final ClassLoader classLoader) {
|
||||
for(int i = 0; i < classes.length; ++i) {
|
||||
if(!Guards.canReferenceDirectly(classLoader, classes[i].getClassLoader())) {
|
||||
return false;
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
|
||||
@Override
|
||||
public Boolean run() {
|
||||
for(final Class<?> clazz: classes) {
|
||||
if(!Guards.canReferenceDirectly(classLoader, clazz.getClassLoader())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, null, GET_CLASS_LOADER_PERMISSION);
|
||||
}
|
||||
|
||||
List<MethodHandle> getMaximallySpecifics(final List<MethodHandle> methods, final LinkerServices linkerServices, final boolean varArg) {
|
||||
|
@ -85,6 +85,11 @@ package jdk.internal.dynalink.beans;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.Permissions;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -218,10 +223,27 @@ class OverloadedDynamicMethod extends DynamicMethod {
|
||||
for(final SingleDynamicMethod method: invokables) {
|
||||
methodHandles.add(method.getTarget(callSiteDescriptor));
|
||||
}
|
||||
return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker();
|
||||
return new OverloadedMethod(methodHandles, this, getCallSiteClassLoader(callSiteDescriptor), callSiteType, linkerServices).getInvoker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final AccessControlContext GET_CALL_SITE_CLASS_LOADER_CONTEXT;
|
||||
static {
|
||||
final Permissions perms = new Permissions();
|
||||
perms.add(new RuntimePermission("getClassLoader"));
|
||||
perms.add(CallSiteDescriptor.GET_LOOKUP_PERMISSION);
|
||||
GET_CALL_SITE_CLASS_LOADER_CONTEXT = new AccessControlContext(
|
||||
new ProtectionDomain[] { new ProtectionDomain(null, perms) });
|
||||
}
|
||||
|
||||
private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
@Override
|
||||
public ClassLoader run() {
|
||||
return callSiteDescriptor.getLookup().lookupClass().getClassLoader();
|
||||
}
|
||||
}, GET_CALL_SITE_CLASS_LOADER_CONTEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,15 +104,20 @@ import jdk.internal.dynalink.support.TypeUtilities;
|
||||
class OverloadedMethod {
|
||||
private final Map<ClassString, MethodHandle> argTypesToMethods = new ConcurrentHashMap<>();
|
||||
private final OverloadedDynamicMethod parent;
|
||||
private final ClassLoader callSiteClassLoader;
|
||||
private final MethodType callSiteType;
|
||||
private final MethodHandle invoker;
|
||||
private final LinkerServices linkerServices;
|
||||
private final ArrayList<MethodHandle> fixArgMethods;
|
||||
private final ArrayList<MethodHandle> varArgMethods;
|
||||
|
||||
OverloadedMethod(final List<MethodHandle> methodHandles, final OverloadedDynamicMethod parent, final MethodType callSiteType,
|
||||
OverloadedMethod(final List<MethodHandle> methodHandles,
|
||||
final OverloadedDynamicMethod parent,
|
||||
final ClassLoader callSiteClassLoader,
|
||||
final MethodType callSiteType,
|
||||
final LinkerServices linkerServices) {
|
||||
this.parent = parent;
|
||||
this.callSiteClassLoader = callSiteClassLoader;
|
||||
final Class<?> commonRetType = getCommonReturnType(methodHandles);
|
||||
this.callSiteType = callSiteType.changeReturnType(commonRetType);
|
||||
this.linkerServices = linkerServices;
|
||||
@ -179,7 +184,7 @@ class OverloadedMethod {
|
||||
}
|
||||
// Avoid keeping references to unrelated classes; this ruins the performance a bit, but avoids class loader
|
||||
// memory leaks.
|
||||
if(classString.isVisibleFrom(parent.getClassLoader())) {
|
||||
if(classString.isVisibleFrom(callSiteClassLoader)) {
|
||||
argTypesToMethods.put(classString, method);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user