diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 5a44adeb294..c3bcbed4e3b 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -315,7 +315,6 @@ module java.base { exports sun.reflect.misc to java.desktop, java.management, - java.management.rmi, java.rmi, java.sql.rowset; exports sun.security.internal.interfaces to diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java index cb318dc65b2..9c0b3d56214 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java @@ -29,24 +29,17 @@ import java.io.IOException; 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; @@ -94,7 +87,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { * RMIServerImpl. Can be null, equivalent to an * empty map. */ - @SuppressWarnings("removal") public RMIConnectionImpl(RMIServerImpl rmiServer, String connectionId, ClassLoader defaultClassLoader, @@ -111,54 +103,13 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { this.mbeanServer = rmiServer.getMBeanServer(); final ClassLoader dcl = defaultClassLoader; - - ClassLoaderRepository repository = AccessController.doPrivileged( - new PrivilegedAction() { - public ClassLoaderRepository run() { - return mbeanServer.getClassLoaderRepository(); - } - }, - withPermissions(new MBeanPermission("*", "getClassLoaderRepository")) - ); - this.classLoaderWithRepository = AccessController.doPrivileged( - new PrivilegedAction() { - public ClassLoaderWithRepository run() { - return new ClassLoaderWithRepository( - repository, - dcl); - } - }, - withPermissions(new RuntimePermission("createClassLoader")) - ); - - this.defaultContextClassLoader = - AccessController.doPrivileged( - new PrivilegedAction() { - @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. @@ -397,7 +348,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { +", unwrapping params with MBean extended ClassLoader."); values = nullIsEmpty(unwrap(params, - getClassLoader(loaderName), + mbeanServer.getClassLoader(loaderName), defaultClassLoader, Object[].class,delegationSubject)); @@ -1249,7 +1200,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { } } - @SuppressWarnings("removal") public NotificationResult fetchNotifications(long clientSequenceNumber, int maxNotifications, long timeout) @@ -1274,19 +1224,22 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { + "returns null to force the client to stop fetching"); return null; } - final long csn = clientSequenceNumber; - final int mn = maxNotifications; - final long t = timeout; - PrivilegedAction action = - new PrivilegedAction() { - 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(); @@ -1311,25 +1264,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { // private classes //------------------------------------------------------------------------ - private class PrivilegedOperation - implements PrivilegedExceptionAction { - - 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); @@ -1352,44 +1286,13 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { // private methods //------------------------------------------------------------------------ - @SuppressWarnings("removal") - private ClassLoader getClassLoader(final ObjectName name) - throws InstanceNotFoundException { - try { - return - AccessController.doPrivileged( - new PrivilegedExceptionAction() { - 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() { - 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) @@ -1402,10 +1305,9 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { } 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; @@ -1414,7 +1316,20 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { } } } 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); @@ -1545,24 +1460,15 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { } } - private static class SetCcl implements PrivilegedExceptionAction { - 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 unwrap(final MarshalledObject mo, final ClassLoader cl, final Class wrappedClass, @@ -1578,32 +1484,33 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { return null; } try { - final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl)); + ClassLoader old = setCcl(cl); try { if (subject != null) { - return Subject.doAs(subject, (PrivilegedExceptionAction) () -> 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 unwrap(final MarshalledObject mo, @@ -1616,18 +1523,10 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { return null; } try { - @SuppressWarnings("removal") - ClassLoader orderCL = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - 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; } @@ -1815,7 +1714,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - ReflectUtil.checkPackageAccess(name); try { super.loadClass(name, resolve); } catch(Exception e) { diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java index 24b9f1055b7..47089dcd252 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -54,9 +54,6 @@ import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RemoteObject; import java.rmi.server.RemoteObjectInvocationHandler; import java.rmi.server.RemoteRef; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; @@ -102,7 +99,6 @@ import javax.naming.NamingException; import javax.rmi.ssl.SslRMIClientSocketFactory; import javax.security.auth.Subject; import jdk.internal.module.Modules; -import sun.reflect.misc.ReflectUtil; import sun.rmi.server.UnicastRef2; import sun.rmi.transport.LiveRef; import java.io.NotSerializableException; @@ -1856,7 +1852,6 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable protected Class resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { String name = classDesc.getName(); - ReflectUtil.checkPackageAccess(name); return Class.forName(name, false, Objects.requireNonNull(loader)); } @@ -1964,51 +1959,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable "\4\0\1\0\14\0\0"; final byte[] pRefByteCode = NoCallStackClassLoader.stringToBytes(pRefByteCodeString); - PrivilegedExceptionAction> action = - new PrivilegedExceptionAction>() { - public Constructor run() throws Exception { - Class thisClass = RMIConnector.class; - ClassLoader thisLoader = thisClass.getClassLoader(); - ProtectionDomain thisProtectionDomain = - thisClass.getProtectionDomain(); - String proxyRefCName = ProxyRef.class.getName(); - ClassLoader cl = - new NoCallStackClassLoader(pRefClassName, - pRefByteCode, - new String[] { proxyRefCName }, - thisLoader, - thisProtectionDomain); - - Module jmxModule = ProxyRef.class.getModule(); - Module rmiModule = RemoteRef.class.getModule(); - - String pkg = packageOf(pRefClassName); - assert pkg != null && pkg.length() > 0 && - !pkg.equals(packageOf(proxyRefCName)); - - ModuleDescriptor descriptor = - ModuleDescriptor.newModule("jdk.remoteref", Set.of(SYNTHETIC)) - .packages(Set.of(pkg)) - .build(); - Module m = Modules.defineModule(cl, descriptor, null); - - // jdk.remoteref needs to read to java.base and jmxModule - Modules.addReads(m, Object.class.getModule()); - Modules.addReads(m, jmxModule); - Modules.addReads(m, rmiModule); - - // jdk.remoteref needs access to ProxyRef class - Modules.addExports(jmxModule, packageOf(proxyRefCName), m); - - // java.management needs to instantiate the fabricated RemoteRef class - Modules.addReads(jmxModule, m); - Modules.addExports(m, pkg, jmxModule); - - Class c = cl.loadClass(pRefClassName); - return c.getConstructor(RemoteRef.class); - } - }; Class serverStubClass; try { @@ -2026,9 +1977,48 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable Constructor constr; try { stubClass = Class.forName(rmiConnectionImplStubClassName); - @SuppressWarnings("removal") - Constructor tmp = (Constructor) AccessController.doPrivileged(action); - constr = tmp; + + Class thisClass = RMIConnector.class; + ClassLoader thisLoader = thisClass.getClassLoader(); + ProtectionDomain thisProtectionDomain = + thisClass.getProtectionDomain(); + + String proxyRefCName = ProxyRef.class.getName(); + ClassLoader cl = + new NoCallStackClassLoader(pRefClassName, + pRefByteCode, + new String[] { proxyRefCName }, + thisLoader, + thisProtectionDomain); + + Module jmxModule = ProxyRef.class.getModule(); + Module rmiModule = RemoteRef.class.getModule(); + + String pkg = packageOf(pRefClassName); + assert pkg != null && pkg.length() > 0 && + !pkg.equals(packageOf(proxyRefCName)); + + ModuleDescriptor descriptor = + ModuleDescriptor.newModule("jdk.remoteref", Set.of(SYNTHETIC)) + .packages(Set.of(pkg)) + .build(); + Module m = Modules.defineModule(cl, descriptor, null); + + // jdk.remoteref needs to read to java.base and jmxModule + Modules.addReads(m, Object.class.getModule()); + Modules.addReads(m, jmxModule); + Modules.addReads(m, rmiModule); + + // jdk.remoteref needs access to ProxyRef class + Modules.addExports(jmxModule, packageOf(proxyRefCName), m); + + // java.management needs to instantiate the fabricated RemoteRef class + Modules.addReads(jmxModule, m); + Modules.addExports(m, pkg, jmxModule); + + Class c = cl.loadClass(pRefClassName); + + constr = c.getConstructor(RemoteRef.class); } catch (Exception e) { logger.error("", "Failed to initialize proxy reference constructor "+ @@ -2172,33 +2162,22 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable //-------------------------------------------------------------------- // Private stuff - Find / Set default class loader //-------------------------------------------------------------------- - @SuppressWarnings("removal") private ClassLoader pushDefaultClassLoader() { final Thread t = Thread.currentThread(); final ClassLoader old = t.getContextClassLoader(); - if (defaultClassLoader != null) - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - if (t.getContextClassLoader() != defaultClassLoader) { - t.setContextClassLoader(defaultClassLoader); - } - return null; - } - }); - return old; + if (defaultClassLoader != null) { + if (t.getContextClassLoader() != defaultClassLoader) { + t.setContextClassLoader(defaultClassLoader); + } + } + return old; } - @SuppressWarnings("removal") private void popDefaultClassLoader(final ClassLoader old) { - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - Thread t = Thread.currentThread(); - if (t.getContextClassLoader() != old) { - t.setContextClassLoader(old); - } - return null; - } - }); + Thread t = Thread.currentThread(); + if (t.getContextClassLoader() != old) { + t.setContextClassLoader(old); + } } //-------------------------------------------------------------------- diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java index d51ca2cd26e..44e85f1bde2 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ import com.sun.jmx.remote.util.EnvHelp; import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; -import sun.reflect.misc.ReflectUtil; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.rmi.transport.LiveRef; @@ -119,7 +118,6 @@ public class RMIJRMPServerImpl extends RMIServerImpl { else if (credentialsTypes != null) { allowedTypes = Arrays.stream(credentialsTypes).filter( s -> s!= null).collect(Collectors.toSet()); - allowedTypes.forEach(ReflectUtil::checkPackageAccess); cFilter = this::newClientCheckInput; } else { allowedTypes = null;