8025758: Enhance Naming management

Enforce package access control with current context. Also reviewed by Alexander Fomin <alexander.fomin@oracle.com>

Reviewed-by: weijun, ahgross
This commit is contained in:
Xue-Lei Andrew Fan 2013-10-16 18:19:11 -07:00
parent da20231112
commit b61f4321b3
2 changed files with 76 additions and 18 deletions

View File

@ -56,9 +56,12 @@ public final class FactoryEnumeration {
* references so as not to prevent GC of the class loader. Each
* weak reference is tagged with the factory's class name so the
* class can be reloaded if the reference is cleared.
*
* @param factories A non-null list
* @param loader The class loader of the list's contents
*
* This internal method is used with Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*/
FactoryEnumeration(List<NamedWeakReference<Object>> factories,
ClassLoader loader) {
@ -79,7 +82,9 @@ public final class FactoryEnumeration {
try {
if (answer == null) { // reload class if weak ref cleared
answer = Class.forName(className, true, loader);
Class<?> cls = Class.forName(className, true, loader);
VersionHelper12.checkPackageAccess(cls);
answer = cls;
}
// Instantiate Class to get factory
answer = ((Class) answer).newInstance();

View File

@ -39,6 +39,7 @@ import java.util.NoSuchElementException;
import java.util.Properties;
import javax.naming.*;
import sun.reflect.misc.ReflectUtil;
/**
* VersionHelper was used by JNDI to accommodate differences between
@ -53,21 +54,39 @@ import javax.naming.*;
final class VersionHelper12 extends VersionHelper {
private boolean getSystemPropsFailed = false;
// workaround to disable additional package access control with
// Thread Context Class Loader (TCCL).
private final static boolean noPackageAccessWithTCCL = "true".equals(
AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
return System.getProperty(
"com.sun.naming.untieAccessContextWithTCCL");
}
}
));
VersionHelper12() {} // Disallow external from creating one of these.
// Disallow external from creating one of these.
VersionHelper12() {
}
public Class<?> loadClass(String className) throws ClassNotFoundException {
ClassLoader cl = getContextClassLoader();
return Class.forName(className, true, cl);
return loadClass(className, getContextClassLoader());
}
/**
* Package private.
*/
* Package private.
*
* This internal method is used with Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*/
Class<?> loadClass(String className, ClassLoader cl)
throws ClassNotFoundException {
return Class.forName(className, true, cl);
Class<?> cls = Class.forName(className, true, cl);
if (!noPackageAccessWithTCCL) {
checkPackageAccess(cls);
}
return cls;
}
/**
@ -75,13 +94,42 @@ final class VersionHelper12 extends VersionHelper {
* @param codebase A non-null, space-separated list of URL strings.
*/
public Class<?> loadClass(String className, String codebase)
throws ClassNotFoundException, MalformedURLException {
ClassLoader cl;
throws ClassNotFoundException, MalformedURLException {
ClassLoader parent = getContextClassLoader();
cl = URLClassLoader.newInstance(getUrlArray(codebase), parent);
ClassLoader cl =
URLClassLoader.newInstance(getUrlArray(codebase), parent);
return Class.forName(className, true, cl);
return loadClass(className, cl);
}
/**
* check package access of a class that is loaded with Thread Context
* Class Loader (TCCL).
*
* Similar to java.lang.ClassLoader.checkPackageAccess()
*/
static void checkPackageAccess(Class<?> cls) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(cls)) {
for (Class<?> intf: cls.getInterfaces()) {
checkPackageAccess(intf);
}
return;
}
final String name = cls.getName();
final int i = name.lastIndexOf('.');
if (i != -1) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
sm.checkPackageAccess(name.substring(0, i));
return null;
}
}, AccessController.getContext());
}
}
}
String getJndiProperty(final int i) {
@ -99,16 +147,12 @@ final class VersionHelper12 extends VersionHelper {
}
String[] getJndiProperties() {
if (getSystemPropsFailed) {
return null; // after one failure, don't bother trying again
}
Properties sysProps = AccessController.doPrivileged(
new PrivilegedAction<Properties>() {
public Properties run() {
try {
return System.getProperties();
} catch (SecurityException e) {
getSystemPropsFailed = true;
return null;
}
}
@ -173,7 +217,17 @@ final class VersionHelper12 extends VersionHelper {
return new InputStreamEnumeration(urls);
}
/**
* Package private.
*
* This internal method makes use of Thread Context Class Loader (TCCL),
* please don't expose this method as public.
*
* Please take care of package access control on the current context
* whenever using TCCL.
*/
ClassLoader getContextClassLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
@ -183,7 +237,6 @@ final class VersionHelper12 extends VersionHelper {
);
}
/**
* Given an enumeration of URLs, an instance of this class represents
* an enumeration of their InputStreams. Each operation on the URL