Skip to content

Commit

Permalink
8344394: Remove SecurityManager and related calls from java.managemen…
Browse files Browse the repository at this point in the history
…t.rmi

Reviewed-by: amenkov
  • Loading branch information
kevinjwalls committed Nov 28, 2024
1 parent 3b21a29 commit fd742af
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 240 deletions.
1 change: 0 additions & 1 deletion src/java.base/share/classes/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,6 @@
exports sun.reflect.misc to
java.desktop,
java.management,
java.management.rmi,
java.rmi,
java.sql.rowset;
exports sun.security.internal.interfaces to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,17 @@
import java.rmi.MarshalledObject;
import java.rmi.UnmarshalException;
import java.rmi.server.Unreferenced;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Permission;
import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletionException;

import javax.management.*;
import javax.management.remote.JMXServerErrorException;
import javax.management.remote.NotificationResult;
import javax.security.auth.Subject;
import sun.reflect.misc.ReflectUtil;

import static javax.management.remote.rmi.RMIConnector.Util.cast;
import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
Expand Down Expand Up @@ -94,7 +87,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced {
* <code>RMIServerImpl</code>. Can be null, equivalent to an
* empty map.
*/
@SuppressWarnings("removal")
public RMIConnectionImpl(RMIServerImpl rmiServer,
String connectionId,
ClassLoader defaultClassLoader,
Expand All @@ -111,54 +103,13 @@ public RMIConnectionImpl(RMIServerImpl rmiServer,
this.mbeanServer = rmiServer.getMBeanServer();

final ClassLoader dcl = defaultClassLoader;

ClassLoaderRepository repository = AccessController.doPrivileged(
new PrivilegedAction<ClassLoaderRepository>() {
public ClassLoaderRepository run() {
return mbeanServer.getClassLoaderRepository();
}
},
withPermissions(new MBeanPermission("*", "getClassLoaderRepository"))
);
this.classLoaderWithRepository = AccessController.doPrivileged(
new PrivilegedAction<ClassLoaderWithRepository>() {
public ClassLoaderWithRepository run() {
return new ClassLoaderWithRepository(
repository,
dcl);
}
},
withPermissions(new RuntimePermission("createClassLoader"))
);

this.defaultContextClassLoader =
AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
@Override
public ClassLoader run() {
return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
dcl);
}
});

serverCommunicatorAdmin = new
RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));

ClassLoaderRepository repository = mbeanServer.getClassLoaderRepository();
classLoaderWithRepository = new ClassLoaderWithRepository(repository, dcl);
defaultContextClassLoader = new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), dcl);
serverCommunicatorAdmin = new RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));
this.env = env;
}

@SuppressWarnings("removal")
private static AccessControlContext withPermissions(Permission ... perms){
Permissions col = new Permissions();

for (Permission thePerm : perms ) {
col.add(thePerm);
}

final ProtectionDomain pd = new ProtectionDomain(null, col);
return new AccessControlContext( new ProtectionDomain[] { pd });
}

private synchronized ServerNotifForwarder getServerNotifFwd() {
// Lazily created when first use. Mainly when
// addNotificationListener is first called.
Expand Down Expand Up @@ -397,7 +348,7 @@ public ObjectInstance createMBean(String className,
+", unwrapping params with MBean extended ClassLoader.");

values = nullIsEmpty(unwrap(params,
getClassLoader(loaderName),
mbeanServer.getClassLoader(loaderName),
defaultClassLoader,
Object[].class,delegationSubject));

Expand Down Expand Up @@ -1249,7 +1200,6 @@ public void removeNotificationListener(ObjectName name,
}
}

@SuppressWarnings("removal")
public NotificationResult fetchNotifications(long clientSequenceNumber,
int maxNotifications,
long timeout)
Expand All @@ -1274,19 +1224,22 @@ public NotificationResult fetchNotifications(long clientSequenceNumber,
+ "returns null to force the client to stop fetching");
return null;
}
final long csn = clientSequenceNumber;
final int mn = maxNotifications;
final long t = timeout;
PrivilegedAction<NotificationResult> action =
new PrivilegedAction<NotificationResult>() {
public NotificationResult run() {
return getServerNotifFwd().fetchNotifs(csn, t, mn);
}
};

if (subject == null) {
return action.run();
return getServerNotifFwd().fetchNotifs(clientSequenceNumber, timeout, maxNotifications);
} else {
return Subject.doAs(subject, action);
try {
return Subject.callAs(subject, () -> getServerNotifFwd().fetchNotifs(clientSequenceNumber, timeout, maxNotifications));
} catch (CompletionException ce) {
Throwable thr = ce.getCause();
if (thr instanceof SecurityException se) {
throw se;
} else if (thr instanceof IOException ioe) {
throw ioe;
} else {
throw new RuntimeException(thr);
}
}
}
} finally {
serverCommunicatorAdmin.rspOutgoing();
Expand All @@ -1311,25 +1264,6 @@ public String toString() {
// private classes
//------------------------------------------------------------------------

private class PrivilegedOperation
implements PrivilegedExceptionAction<Object> {

public PrivilegedOperation(int operation, Object[] params) {
this.operation = operation;
this.params = params;
}

public Object run() throws Exception {
return doOperation(operation, params);
}

private int operation;
private Object[] params;
}

//------------------------------------------------------------------------
// private classes
//------------------------------------------------------------------------
private class RMIServerCommunicatorAdmin extends ServerCommunicatorAdmin {
public RMIServerCommunicatorAdmin(long timeout) {
super(timeout);
Expand All @@ -1352,44 +1286,13 @@ protected void doStop() {
// private methods
//------------------------------------------------------------------------

@SuppressWarnings("removal")
private ClassLoader getClassLoader(final ObjectName name)
throws InstanceNotFoundException {
try {
return
AccessController.doPrivileged(
new PrivilegedExceptionAction<ClassLoader>() {
public ClassLoader run() throws InstanceNotFoundException {
return mbeanServer.getClassLoader(name);
}
},
withPermissions(new MBeanPermission("*", "getClassLoader"))
);
} catch (PrivilegedActionException pe) {
throw (InstanceNotFoundException) extractException(pe);
}
}

@SuppressWarnings("removal")
private ClassLoader getClassLoaderFor(final ObjectName name)
throws InstanceNotFoundException {
try {
return (ClassLoader)
AccessController.doPrivileged(
new PrivilegedExceptionAction<Object>() {
public Object run() throws InstanceNotFoundException {
return mbeanServer.getClassLoaderFor(name);
}
},
withPermissions(new MBeanPermission("*", "getClassLoaderFor"))
);
} catch (PrivilegedActionException pe) {
throw (InstanceNotFoundException) extractException(pe);
}

return mbeanServer.getClassLoaderFor(name);
}

/** @throws UnsupportedOperationException {@inheritDoc} */
@SuppressWarnings("removal")
private Object doPrivilegedOperation(final int operation,
final Object[] params,
final Subject delegationSubject)
Expand All @@ -1402,10 +1305,9 @@ private Object doPrivilegedOperation(final int operation,
}
serverCommunicatorAdmin.reqIncoming();
try {
PrivilegedOperation op = new PrivilegedOperation(operation, params);
if (subject == null) {
try {
return op.run();
return doOperation(operation, params);
} catch (Exception e) {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
Expand All @@ -1414,7 +1316,20 @@ private Object doPrivilegedOperation(final int operation,
}
}
} else {
return Subject.doAs(subject, op);
try {
return Subject.callAs(subject, () -> doOperation(operation, params));
} catch (CompletionException ce) {
Throwable thr = ce.getCause();
if (thr instanceof SecurityException se) {
throw se;
} else if (thr instanceof IOException ioe) {
throw ioe;
} else if (thr instanceof Exception e1) {
throw new PrivilegedActionException(e1);
} else {
throw new RuntimeException(thr);
}
}
}
} catch (Error e) {
throw new JMXServerErrorException(e.toString(),e);
Expand Down Expand Up @@ -1545,24 +1460,15 @@ private Object doOperation(int operation, Object[] params)
}
}

private static class SetCcl implements PrivilegedExceptionAction<ClassLoader> {
private final ClassLoader classLoader;

SetCcl(ClassLoader classLoader) {
this.classLoader = classLoader;
}

public ClassLoader run() {
Thread currentThread = Thread.currentThread();
ClassLoader old = currentThread.getContextClassLoader();
if (classLoader != old) {
currentThread.setContextClassLoader(classLoader);
}
return old;
private static ClassLoader setCcl(ClassLoader classLoader) {
Thread currentThread = Thread.currentThread();
ClassLoader old = currentThread.getContextClassLoader();
if (classLoader != old) {
currentThread.setContextClassLoader(classLoader);
}
return old;
}

@SuppressWarnings("removal")
private <T> T unwrap(final MarshalledObject<?> mo,
final ClassLoader cl,
final Class<T> wrappedClass,
Expand All @@ -1578,32 +1484,33 @@ private <T> T unwrap(final MarshalledObject<?> mo,
return null;
}
try {
final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl));
ClassLoader old = setCcl(cl);
try {
if (subject != null) {
return Subject.doAs(subject, (PrivilegedExceptionAction<T>) () -> wrappedClass.cast(mo.get()));
try {
return Subject.callAs(subject, () -> wrappedClass.cast(mo.get()));
} catch (CompletionException ce) {
Throwable thr = ce.getCause();
if (thr instanceof Exception e) {
throw e;
} else {
throw new RuntimeException(thr);
}
}
} else {
return wrappedClass.cast(mo.get());
}
} finally {
AccessController.doPrivileged(new SetCcl(old));
setCcl(old);
}
} catch (PrivilegedActionException pe) {
Exception e = extractException(pe);
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
}
if (e instanceof ClassNotFoundException) {
throw new UnmarshalException(e.toString(), e);
}
logger.warning("unwrap", "Failed to unmarshall object: " + e);
logger.debug("unwrap", e);
}catch (ClassNotFoundException ex) {
logger.warning("unwrap", "Failed to unmarshall object: " + ex);
logger.debug("unwrap", ex);
throw new UnmarshalException(ex.toString(), ex);
throw new UnmarshalException(e.toString(), e);
}
return null;
}

private <T> T unwrap(final MarshalledObject<?> mo,
Expand All @@ -1616,18 +1523,10 @@ private <T> T unwrap(final MarshalledObject<?> mo,
return null;
}
try {
@SuppressWarnings("removal")
ClassLoader orderCL = AccessController.doPrivileged(
new PrivilegedExceptionAction<ClassLoader>() {
public ClassLoader run() throws Exception {
return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
new OrderClassLoaders(cl1, cl2));
}
}
);
ClassLoader orderCL = new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
new OrderClassLoaders(cl1, cl2));
return unwrap(mo, orderCL, wrappedClass,delegationSubject);
} catch (PrivilegedActionException pe) {
Exception e = extractException(pe);
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
}
Expand Down Expand Up @@ -1815,7 +1714,6 @@ private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) {
@Override
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
ReflectUtil.checkPackageAccess(name);
try {
super.loadClass(name, resolve);
} catch(Exception e) {
Expand Down
Loading

1 comment on commit fd742af

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.