8025758: Enhance Naming management
Summary: Enforce package access control with current context. Also reviewed by Alexander Fomin <alexander.fomin@oracle.com>
Reviewed-by: weijun, ahgross
--- a/jdk/src/share/classes/com/sun/naming/internal/FactoryEnumeration.java Wed Oct 16 13:26:05 2013 +0400
+++ b/jdk/src/share/classes/com/sun/naming/internal/FactoryEnumeration.java Wed Oct 16 18:19:11 2013 -0700
@@ -56,9 +56,12 @@
* 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 @@
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();
--- a/jdk/src/share/classes/com/sun/naming/internal/VersionHelper12.java Wed Oct 16 13:26:05 2013 +0400
+++ b/jdk/src/share/classes/com/sun/naming/internal/VersionHelper12.java Wed Oct 16 18:19:11 2013 -0700
@@ -39,6 +39,7 @@
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 @@
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 @@
* @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 loadClass(className, cl);
+ }
- return Class.forName(className, true, 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 @@
}
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 @@
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 @@
);
}
-
/**
* Given an enumeration of URLs, an instance of this class represents
* an enumeration of their InputStreams. Each operation on the URL