From 97583c8f0d159288497d7f8ec43d20105ec2647a Mon Sep 17 00:00:00 2001 From: Stuart Marks Date: Tue, 30 Aug 2011 17:29:36 -0700 Subject: [PATCH] 7083012: fix for RMI Registry Reviewed-by: jdn, valeriep --- .../sun/rmi/registry/RegistryImpl.java | 81 ++++++++++++++++++- .../classes/sun/rmi/server/LoaderHandler.java | 6 +- 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java index 4878609c088..465260da87b 100644 --- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java @@ -38,13 +38,23 @@ import java.rmi.server.ServerNotActiveException; import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; +import java.security.AccessControlContext; +import java.security.AccessController; +import java.security.CodeSource; +import java.security.Policy; import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.ProtectionDomain; import java.text.MessageFormat; +import sun.rmi.server.LoaderHandler; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.rmi.transport.LiveRef; import sun.rmi.transport.ObjectTable; import sun.rmi.transport.Target; +import sun.security.action.GetPropertyAction; /** * A "registry" exists on every node that allows RMI connections to @@ -325,6 +335,19 @@ public class RegistryImpl extends java.rmi.server.RemoteServer URL[] urls = sun.misc.URLClassPath.pathToURLs(envcp); ClassLoader cl = new URLClassLoader(urls); + String codebaseProperty = null; + String prop = java.security.AccessController.doPrivileged( + new GetPropertyAction("java.rmi.server.codebase")); + if (prop != null && prop.trim().length() > 0) { + codebaseProperty = prop; + } + URL[] codebaseURLs = null; + if (codebaseProperty != null) { + codebaseURLs = sun.misc.URLClassPath.pathToURLs(codebaseProperty); + } else { + codebaseURLs = new URL[0]; + } + /* * Fix bugid 4242317: Classes defined by this class loader should * be annotated with the value of the "java.rmi.server.codebase" @@ -334,11 +357,19 @@ public class RegistryImpl extends java.rmi.server.RemoteServer Thread.currentThread().setContextClassLoader(cl); - int regPort = Registry.REGISTRY_PORT; - if (args.length >= 1) { - regPort = Integer.parseInt(args[0]); + final int regPort = (args.length >= 1) ? Integer.parseInt(args[0]) + : Registry.REGISTRY_PORT; + try { + registry = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public RegistryImpl run() throws RemoteException { + return new RegistryImpl(regPort); + } + }, getAccessControlContext(codebaseURLs)); + } catch (PrivilegedActionException ex) { + throw (RemoteException) ex.getException(); } - registry = new RegistryImpl(regPort); + // prevent registry from exiting while (true) { try { @@ -358,4 +389,46 @@ public class RegistryImpl extends java.rmi.server.RemoteServer } System.exit(1); } + + /** + * Generates an AccessControlContext from several URLs. + * The approach used here is taken from the similar method + * getAccessControlContext() in the sun.applet.AppletPanel class. + */ + private static AccessControlContext getAccessControlContext(URL[] urls) { + // begin with permissions granted to all code in current policy + PermissionCollection perms = AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public PermissionCollection run() { + CodeSource codesource = new CodeSource(null, + (java.security.cert.Certificate[]) null); + Policy p = java.security.Policy.getPolicy(); + if (p != null) { + return p.getPermissions(codesource); + } else { + return new Permissions(); + } + } + }); + + /* + * Anyone can connect to the registry and the registry can connect + * to and possibly download stubs from anywhere. Downloaded stubs and + * related classes themselves are more tightly limited by RMI. + */ + perms.add(new SocketPermission("*", "connect,accept")); + + // add permissions required to load from codebase URL path + LoaderHandler.addPermissionsForURLs(urls, perms, false); + + /* + * Create an AccessControlContext that consists of a single + * protection domain with only the permissions calculated above. + */ + ProtectionDomain pd = new ProtectionDomain( + new CodeSource((urls.length > 0 ? urls[0] : null), + (java.security.cert.Certificate[]) null), + perms); + return new AccessControlContext(new ProtectionDomain[] { pd }); + } } diff --git a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java index 541c7840e08..52d9ee55172 100644 --- a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java +++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java @@ -1031,9 +1031,9 @@ public final class LoaderHandler { * loader. A given permission is only added to the collection if * it is not already implied by the collection. */ - private static void addPermissionsForURLs(URL[] urls, - PermissionCollection perms, - boolean forLoader) + public static void addPermissionsForURLs(URL[] urls, + PermissionCollection perms, + boolean forLoader) { for (int i = 0; i < urls.length; i++) { URL url = urls[i];