# HG changeset patch
# User robm
# Date 1500161350 -3600
# Node ID 0e846618238e7d0470c38ecc721dee785cdfd9dc
# Parent 8f1c0d565d1322e0b1357c59b8a4fbb0bd429b48
8174770: Check registry registration location
Reviewed-by: rriggs
diff -r 8f1c0d565d13 -r 0e846618238e make/sun/rmi/rmi/Makefile
--- a/make/sun/rmi/rmi/Makefile Sat Jul 15 21:26:47 2017 +0100
+++ b/make/sun/rmi/rmi/Makefile Sun Jul 16 00:29:10 2017 +0100
@@ -52,15 +52,9 @@
include $(BUILDDIR)/common/Rules.gmk
#
-# Full package names of implementations requiring stubs
-#
-REMOTE_impls = \
- sun.rmi.registry.RegistryImpl
-
-#
# The java-rmi.cgi script in bin/ only gets delivered in certain situations
#
-BUILD_TARGETS = stubs
+BUILD_TARGETS =
ifeq ($(PLATFORM), linux)
BUILD_TARGETS += bin
endif
@@ -74,30 +68,6 @@
clean clobber:: bin.clean
-
-#
-# Compile stubs and skeletons for remote implementations
-# (use -v1.1 for backward interoperability)
-#
-# gnumake 3.78.1 on windows attempts to build the target even
-# though it exists. Not sure why, but a check for file existence
-# has been added...
-#
-REMOTE_files = $(subst .,/,$(REMOTE_impls))
-FILES_classes = $(REMOTE_files:%=$(CLASSBINDIR)/%.class)
-FILES_stubs = $(REMOTE_files:%=$(CLASSBINDIR)/%_Stub.class)
-FILES_skels = $(REMOTE_files:%=$(CLASSBINDIR)/%_Skel.class)
-
-$(FILES_stubs) $(FILES_skels): $(FILES_classes)
- if [ ! -s $@ ] ; \
- then $(RMIC) -v1.1 -classpath \
- "$(CLASSBINDIR)" \
- -d $(CLASSBINDIR) '$(subst /,.,$(<:$(CLASSBINDIR)/%.class=%))' ; \
- fi
- @$(java-vm-cleanup)
-
-stubs: $(FILES_stubs) $(FILES_skels)
-
bin: $(BINDIR)/java-rmi.cgi
$(BINDIR)/java-rmi.cgi: $(PLATFORM_SRC)/bin/java-rmi.cgi.sh
@@ -107,5 +77,5 @@
bin.clean:
$(RM) $(BINDIR)/java-rmi.cgi
-.PHONY: stubs bin bin.clean
+.PHONY: bin bin.clean
diff -r 8f1c0d565d13 -r 0e846618238e src/share/classes/sun/management/jmxremote/SingleEntryRegistry.java
--- a/src/share/classes/sun/management/jmxremote/SingleEntryRegistry.java Sat Jul 15 21:26:47 2017 +0100
+++ b/src/share/classes/sun/management/jmxremote/SingleEntryRegistry.java Sun Jul 16 00:29:10 2017 +0100
@@ -32,6 +32,7 @@
package sun.management.jmxremote;
+import sun.misc.ObjectInputFilter;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.Remote;
@@ -56,7 +57,12 @@
String name,
Remote object)
throws RemoteException {
- super(port, csf, ssf);
+ super(port, csf, ssf, new ObjectInputFilter() {
+ @Override
+ public Status checkInput(ObjectInputFilter.FilterInfo info) {
+ return SingleEntryRegistry.singleRegistryFilter(info);
+ }
+ });
this.name = name;
this.object = object;
}
@@ -84,6 +90,23 @@
throw new AccessException("Cannot modify this registry");
}
+ /**
+ * ObjectInputFilter to check parameters to SingleEntryRegistry.
+ * Since it is a read-only Registry, no classes are accepted.
+ * String arguments are accepted without passing them to the serialFilter.
+ *
+ * @param info a reference to the serialization filter information
+ * @return Status.REJECTED if parameters are out of range
+ */
+ private static ObjectInputFilter.Status singleRegistryFilter(ObjectInputFilter.FilterInfo info) {
+ return (info.serialClass() != null ||
+ info.depth() > 2 ||
+ info.references() > 4 ||
+ info.arrayLength() >= 0)
+ ? ObjectInputFilter.Status.REJECTED
+ : ObjectInputFilter.Status.ALLOWED;
+ }
+
private final String name;
private final Remote object;
diff -r 8f1c0d565d13 -r 0e846618238e src/share/classes/sun/rmi/registry/RegistryImpl.java
--- a/src/share/classes/sun/rmi/registry/RegistryImpl.java Sat Jul 15 21:26:47 2017 +0100
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java Sun Jul 16 00:29:10 2017 +0100
@@ -69,6 +69,10 @@
* registry.
*
* The LocateRegistry class is used to obtain registry for different hosts.
+ *
+ * The default RegistryImpl exported restricts access to clients on the local host
+ * for the methods {@link #bind}, {@link #rebind}, {@link #unbind} by checking
+ * the client host in the skeleton.
*
* @see java.rmi.registry.LocateRegistry
*/
@@ -107,11 +111,18 @@
*/
private static final ObjectInputFilter registryFilter =
AccessController.doPrivileged(new PrivilegedAction() {
- @Override
- public ObjectInputFilter run() {
- return initRegistryFilter();
- }
- });
+ @Override
+ public ObjectInputFilter run() {
+ return initRegistryFilter();
+ }
+ });
+
+ private static final ObjectInputFilter defaultFilter = new ObjectInputFilter() {
+ @Override
+ public Status checkInput(ObjectInputFilter.FilterInfo info) {
+ return RegistryImpl.registryFilter(info);
+ }
+ };
/**
* Initialize the registryFilter from the security properties or system property; if any
@@ -142,8 +153,22 @@
RMIServerSocketFactory ssf)
throws RemoteException
{
+ this(port, csf, ssf, defaultFilter);
+ }
+
+
+ /**
+ * Construct a new RegistryImpl on the specified port with the
+ * given custom socket factory pair and ObjectInputFilter.
+ */
+ public RegistryImpl(int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf,
+ ObjectInputFilter serialFilter)
+ throws RemoteException
+ {
LiveRef lref = new LiveRef(id, port, csf, ssf);
- setup(new UnicastServerRef2(lref, registryFilter()));
+ setup(new UnicastServerRef2(lref, serialFilter));
}
/**
@@ -153,7 +178,7 @@
throws RemoteException
{
LiveRef lref = new LiveRef(id, port);
- setup(new UnicastServerRef(lref, registryFilter()));
+ setup(new UnicastServerRef(lref, defaultFilter));
}
/*
@@ -194,7 +219,8 @@
public void bind(String name, Remote obj)
throws RemoteException, AlreadyBoundException, AccessException
{
- checkAccess("Registry.bind");
+ // The access check preventing remote access is done in the skeleton
+ // and is not applicable to local access.
synchronized (bindings) {
Remote curr = bindings.get(name);
if (curr != null)
@@ -211,7 +237,8 @@
public void unbind(String name)
throws RemoteException, NotBoundException, AccessException
{
- checkAccess("Registry.unbind");
+ // The access check preventing remote access is done in the skeleton
+ // and is not applicable to local access.
synchronized (bindings) {
Remote obj = bindings.get(name);
if (obj == null)
@@ -227,7 +254,8 @@
public void rebind(String name, Remote obj)
throws RemoteException, AccessException
{
- checkAccess("Registry.rebind");
+ // The access check preventing remote access is done in the skeleton
+ // and is not applicable to local access.
bindings.put(name, obj);
}
@@ -254,7 +282,6 @@
* The client must be on same the same host as this server.
*/
public static void checkAccess(String op) throws AccessException {
-
try {
/*
* Get client host that this registry operation was made from.
@@ -280,7 +307,7 @@
if (clientHost.isAnyLocalAddress()) {
throw new AccessException(
- "Registry." + op + " disallowed; origin unknown");
+ op + " disallowed; origin unknown");
}
try {
@@ -303,7 +330,7 @@
// must have been an IOException
throw new AccessException(
- "Registry." + op + " disallowed; origin " +
+ op + " disallowed; origin " +
clientHost + " is non-local host");
}
}
@@ -312,8 +339,7 @@
* Local call from this VM: allow access.
*/
} catch (java.net.UnknownHostException ex) {
- throw new AccessException("Registry." + op +
- " disallowed; origin is unknown host");
+ throw new AccessException(op + " disallowed; origin is unknown host");
}
}
@@ -360,53 +386,48 @@
* {@link ObjectInputFilter.Status#REJECTED} if rejected,
* otherwise {@link ObjectInputFilter.Status#UNDECIDED}
*/
- private static ObjectInputFilter registryFilter() {
- return new ObjectInputFilter() {
- @Override
- public ObjectInputFilter.Status checkInput(ObjectInputFilter.FilterInfo filterInfo) {
- if (registryFilter != null) {
- ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo);
- if (status != ObjectInputFilter.Status.UNDECIDED) {
- // The Registry filter can override the built-in white-list
- return status;
- }
- }
+ private static ObjectInputFilter.Status registryFilter(ObjectInputFilter.FilterInfo filterInfo) {
+ if (registryFilter != null) {
+ ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo);
+ if (status != ObjectInputFilter.Status.UNDECIDED) {
+ // The Registry filter can override the built-in white-list
+ return status;
+ }
+ }
- if (filterInfo.depth() > REGISTRY_MAX_DEPTH) {
+ if (filterInfo.depth() > REGISTRY_MAX_DEPTH) {
+ return ObjectInputFilter.Status.REJECTED;
+ }
+ Class> clazz = filterInfo.serialClass();
+ if (clazz != null) {
+ if (clazz.isArray()) {
+ if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) {
return ObjectInputFilter.Status.REJECTED;
}
- Class> clazz = filterInfo.serialClass();
- if (clazz != null) {
- if (clazz.isArray()) {
- if (filterInfo.arrayLength() >= 0 && filterInfo.arrayLength() > REGISTRY_MAX_ARRAY_SIZE) {
- return ObjectInputFilter.Status.REJECTED;
- }
- do {
- // Arrays are allowed depending on the component type
- clazz = clazz.getComponentType();
- } while (clazz.isArray());
- }
- if (clazz.isPrimitive()) {
- // Arrays of primitives are allowed
- return ObjectInputFilter.Status.ALLOWED;
- }
- if (String.class == clazz
- || java.lang.Number.class.isAssignableFrom(clazz)
- || Remote.class.isAssignableFrom(clazz)
- || java.lang.reflect.Proxy.class.isAssignableFrom(clazz)
- || UnicastRef.class.isAssignableFrom(clazz)
- || RMIClientSocketFactory.class.isAssignableFrom(clazz)
- || RMIServerSocketFactory.class.isAssignableFrom(clazz)
- || java.rmi.activation.ActivationID.class.isAssignableFrom(clazz)
- || java.rmi.server.UID.class.isAssignableFrom(clazz)) {
- return ObjectInputFilter.Status.ALLOWED;
- } else {
- return ObjectInputFilter.Status.REJECTED;
- }
- }
- return ObjectInputFilter.Status.UNDECIDED;
+ do {
+ // Arrays are allowed depending on the component type
+ clazz = clazz.getComponentType();
+ } while (clazz.isArray());
+ }
+ if (clazz.isPrimitive()) {
+ // Arrays of primitives are allowed
+ return ObjectInputFilter.Status.ALLOWED;
}
- };
+ if (String.class == clazz
+ || java.lang.Number.class.isAssignableFrom(clazz)
+ || Remote.class.isAssignableFrom(clazz)
+ || java.lang.reflect.Proxy.class.isAssignableFrom(clazz)
+ || UnicastRef.class.isAssignableFrom(clazz)
+ || RMIClientSocketFactory.class.isAssignableFrom(clazz)
+ || RMIServerSocketFactory.class.isAssignableFrom(clazz)
+ || java.rmi.activation.ActivationID.class.isAssignableFrom(clazz)
+ || java.rmi.server.UID.class.isAssignableFrom(clazz)) {
+ return ObjectInputFilter.Status.ALLOWED;
+ } else {
+ return ObjectInputFilter.Status.REJECTED;
+ }
+ }
+ return ObjectInputFilter.Status.UNDECIDED;
}
/**
diff -r 8f1c0d565d13 -r 0e846618238e src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl_Skel.java Sun Jul 16 00:29:10 2017 +0100
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package sun.rmi.registry;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.rmi.AccessException;
+import java.rmi.server.RemoteCall;
+
+import sun.rmi.transport.Connection;
+import sun.rmi.transport.StreamRemoteCall;
+import sun.rmi.transport.tcp.TCPConnection;
+
+/**
+ * Skeleton to dispatch RegistryImpl methods.
+ * Originally generated by RMIC but frozen to match the stubs.
+ */
+@SuppressWarnings({"deprecation", "serial"})
+public final class RegistryImpl_Skel
+ implements java.rmi.server.Skeleton {
+ private static final java.rmi.server.Operation[] operations = {
+ new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote)"),
+ new java.rmi.server.Operation("java.lang.String list()[]"),
+ new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String)"),
+ new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote)"),
+ new java.rmi.server.Operation("void unbind(java.lang.String)")
+ };
+
+ private static final long interfaceHash = 4905912898345647071L;
+
+ public java.rmi.server.Operation[] getOperations() {
+ return operations.clone();
+ }
+
+ public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
+ throws java.lang.Exception {
+ if (hash != interfaceHash)
+ throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
+
+ sun.rmi.registry.RegistryImpl server = (sun.rmi.registry.RegistryImpl) obj;
+ switch (opnum) {
+ case 0: // bind(String, Remote)
+ {
+ // Check access before reading the arguments
+ RegistryImpl.checkAccess("Registry.bind");
+
+ java.lang.String $param_String_1;
+ java.rmi.Remote $param_Remote_2;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_String_1 = (java.lang.String) in.readObject();
+ $param_Remote_2 = (java.rmi.Remote) in.readObject();
+ } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ } finally {
+ call.releaseInputStream();
+ }
+ server.bind($param_String_1, $param_Remote_2);
+ try {
+ call.getResultStream(true);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 1: // list()
+ {
+ call.releaseInputStream();
+ java.lang.String[] $result = server.list();
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ out.writeObject($result);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 2: // lookup(String)
+ {
+ java.lang.String $param_String_1;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_String_1 = (java.lang.String) in.readObject();
+ } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ } finally {
+ call.releaseInputStream();
+ }
+ java.rmi.Remote $result = server.lookup($param_String_1);
+ try {
+ java.io.ObjectOutput out = call.getResultStream(true);
+ out.writeObject($result);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 3: // rebind(String, Remote)
+ {
+ // Check access before reading the arguments
+ RegistryImpl.checkAccess("Registry.rebind");
+
+ java.lang.String $param_String_1;
+ java.rmi.Remote $param_Remote_2;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_String_1 = (java.lang.String) in.readObject();
+ $param_Remote_2 = (java.rmi.Remote) in.readObject();
+ } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ } finally {
+ call.releaseInputStream();
+ }
+ server.rebind($param_String_1, $param_Remote_2);
+ try {
+ call.getResultStream(true);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ case 4: // unbind(String)
+ {
+ // Check access before reading the arguments
+ RegistryImpl.checkAccess("Registry.unbind");
+
+ java.lang.String $param_String_1;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $param_String_1 = (java.lang.String) in.readObject();
+ } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
+ } finally {
+ call.releaseInputStream();
+ }
+ server.unbind($param_String_1);
+ try {
+ call.getResultStream(true);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling return", e);
+ }
+ break;
+ }
+
+ default:
+ throw new java.rmi.UnmarshalException("invalid method number");
+ }
+ }
+}
diff -r 8f1c0d565d13 -r 0e846618238e src/share/classes/sun/rmi/registry/RegistryImpl_Stub.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl_Stub.java Sun Jul 16 00:29:10 2017 +0100
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.rmi.registry;
+/**
+ * Stubs to invoke RegistryImpl remote methods.
+ * Originally generated from RMIC but frozen to match RegistryImpl_Skel.
+ */
+@SuppressWarnings({"deprecation", "serial"})
+public final class RegistryImpl_Stub
+ extends java.rmi.server.RemoteStub
+ implements java.rmi.registry.Registry, java.rmi.Remote {
+ private static final java.rmi.server.Operation[] operations = {
+ new java.rmi.server.Operation("void bind(java.lang.String, java.rmi.Remote)"),
+ new java.rmi.server.Operation("java.lang.String list()[]"),
+ new java.rmi.server.Operation("java.rmi.Remote lookup(java.lang.String)"),
+ new java.rmi.server.Operation("void rebind(java.lang.String, java.rmi.Remote)"),
+ new java.rmi.server.Operation("void unbind(java.lang.String)")
+ };
+
+ private static final long interfaceHash = 4905912898345647071L;
+
+ // constructors
+ public RegistryImpl_Stub() {
+ super();
+ }
+
+ public RegistryImpl_Stub(java.rmi.server.RemoteRef ref) {
+ super(ref);
+ }
+
+ // methods from remote interfaces
+
+ // implementation of bind(String, Remote)
+ public void bind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2)
+ throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException {
+ try {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_String_1);
+ out.writeObject($param_Remote_2);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ ref.done(call);
+ } catch (java.lang.RuntimeException e) {
+ throw e;
+ } catch (java.rmi.RemoteException e) {
+ throw e;
+ } catch (java.rmi.AlreadyBoundException e) {
+ throw e;
+ } catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ // implementation of list()
+ public java.lang.String[] list()
+ throws java.rmi.AccessException, java.rmi.RemoteException {
+ try {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
+ ref.invoke(call);
+ java.lang.String[] $result;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $result = (java.lang.String[]) in.readObject();
+ } catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ } catch (java.lang.ClassNotFoundException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ } finally {
+ ref.done(call);
+ }
+ return $result;
+ } catch (java.lang.RuntimeException e) {
+ throw e;
+ } catch (java.rmi.RemoteException e) {
+ throw e;
+ } catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ // implementation of lookup(String)
+ public java.rmi.Remote lookup(java.lang.String $param_String_1)
+ throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
+ try {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_String_1);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ java.rmi.Remote $result;
+ try {
+ java.io.ObjectInput in = call.getInputStream();
+ $result = (java.rmi.Remote) in.readObject();
+ } catch (java.io.IOException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ } catch (java.lang.ClassNotFoundException e) {
+ throw new java.rmi.UnmarshalException("error unmarshalling return", e);
+ } finally {
+ ref.done(call);
+ }
+ return $result;
+ } catch (java.lang.RuntimeException e) {
+ throw e;
+ } catch (java.rmi.RemoteException e) {
+ throw e;
+ } catch (java.rmi.NotBoundException e) {
+ throw e;
+ } catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ // implementation of rebind(String, Remote)
+ public void rebind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2)
+ throws java.rmi.AccessException, java.rmi.RemoteException {
+ try {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_String_1);
+ out.writeObject($param_Remote_2);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ ref.done(call);
+ } catch (java.lang.RuntimeException e) {
+ throw e;
+ } catch (java.rmi.RemoteException e) {
+ throw e;
+ } catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+
+ // implementation of unbind(String)
+ public void unbind(java.lang.String $param_String_1)
+ throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
+ try {
+ java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 4, interfaceHash);
+ try {
+ java.io.ObjectOutput out = call.getOutputStream();
+ out.writeObject($param_String_1);
+ } catch (java.io.IOException e) {
+ throw new java.rmi.MarshalException("error marshalling arguments", e);
+ }
+ ref.invoke(call);
+ ref.done(call);
+ } catch (java.lang.RuntimeException e) {
+ throw e;
+ } catch (java.rmi.RemoteException e) {
+ throw e;
+ } catch (java.rmi.NotBoundException e) {
+ throw e;
+ } catch (java.lang.Exception e) {
+ throw new java.rmi.UnexpectedException("undeclared checked exception", e);
+ }
+ }
+}
diff -r 8f1c0d565d13 -r 0e846618238e src/share/classes/sun/rmi/server/Activation.java
--- a/src/share/classes/sun/rmi/server/Activation.java Sat Jul 15 21:26:47 2017 +0100
+++ b/src/share/classes/sun/rmi/server/Activation.java Sun Jul 16 00:29:10 2017 +0100
@@ -30,6 +30,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
@@ -105,7 +106,6 @@
import sun.rmi.log.ReliableLog;
import sun.rmi.registry.RegistryImpl;
import sun.rmi.runtime.NewThreadAction;
-import sun.rmi.server.UnicastServerRef;
import sun.rmi.transport.LiveRef;
import sun.security.action.GetBooleanAction;
import sun.security.action.GetIntegerAction;
@@ -345,6 +345,7 @@
throw new AccessException(
"binding ActivationSystem is disallowed");
} else {
+ RegistryImpl.checkAccess("ActivationSystem.bind");
super.bind(name, obj);
}
}
@@ -356,6 +357,7 @@
throw new AccessException(
"unbinding ActivationSystem is disallowed");
} else {
+ RegistryImpl.checkAccess("ActivationSystem.unbind");
super.unbind(name);
}
}
@@ -368,6 +370,7 @@
throw new AccessException(
"binding ActivationSystem is disallowed");
} else {
+ RegistryImpl.checkAccess("ActivationSystem.rebind");
super.rebind(name, obj);
}
}
@@ -458,6 +461,33 @@
}
+ /**
+ * SameHostOnlyServerRef checks that access is from a local client
+ * before the parameters are deserialized. The unmarshalCustomCallData
+ * hook is used to check the network address of the caller
+ * with RegistryImpl.checkAccess().
+ * The kind of access is retained for an exception if one is thrown.
+ */
+ static class SameHostOnlyServerRef extends UnicastServerRef {
+ private static final long serialVersionUID = 1234L;
+ private String accessKind; // an exception message
+
+ /**
+ * Construct a new SameHostOnlyServerRef from a LiveRef.
+ * @param lref a LiveRef
+ */
+ SameHostOnlyServerRef(LiveRef lref, String accessKind) {
+ super(lref);
+ this.accessKind = accessKind;
+ }
+
+ @Override
+ protected void unmarshalCustomCallData(ObjectInput in) throws IOException, ClassNotFoundException {
+ RegistryImpl.checkAccess(accessKind);
+ super.unmarshalCustomCallData(in);
+ }
+ }
+
class ActivationSystemImpl
extends RemoteServer
implements ActivationSystem
@@ -475,7 +505,8 @@
* 'this' can be exported.
*/
LiveRef lref = new LiveRef(new ObjID(4), port, null, ssf);
- UnicastServerRef uref = new UnicastServerRef(lref);
+ UnicastServerRef uref = new SameHostOnlyServerRef(lref,
+ "ActivationSystem.nonLocalAccess");
ref = uref;
uref.exportObject(this, null);
}
@@ -484,8 +515,8 @@
throws ActivationException, UnknownGroupException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.registerObject");
-
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
ActivationGroupID groupID = desc.getGroupID();
ActivationID id = new ActivationID(activatorStub);
getGroupEntry(groupID).registerObject(id, desc, true);
@@ -496,15 +527,18 @@
throws ActivationException, UnknownObjectException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.unregisterObject");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
getGroupEntry(id).unregisterObject(id, true);
}
public ActivationGroupID registerGroup(ActivationGroupDesc desc)
throws ActivationException, RemoteException
{
+ Thread.dumpStack();
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.registerGroup");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
checkArgs(desc, null);
ActivationGroupID id = new ActivationGroupID(systemStub);
@@ -521,7 +555,8 @@
throws ActivationException, UnknownGroupException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.activeGroup");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
getGroupEntry(id).activeGroup(group, incarnation);
return monitor;
@@ -531,7 +566,8 @@
throws ActivationException, UnknownGroupException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.unregisterGroup");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
// remove entry before unregister so state is updated before
// logged
@@ -543,7 +579,8 @@
throws ActivationException, UnknownObjectException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.setActivationDesc");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
if (!getGroupID(id).equals(desc.getGroupID())) {
throw new ActivationException(
@@ -557,8 +594,8 @@
throws ActivationException, UnknownGroupException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess(
- "ActivationSystem.setActivationGroupDesc");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
checkArgs(desc, null);
return getGroupEntry(id).setActivationGroupDesc(id, desc, true);
@@ -568,7 +605,8 @@
throws ActivationException, UnknownObjectException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess("ActivationSystem.getActivationDesc");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
return getGroupEntry(id).getActivationDesc(id);
}
@@ -577,8 +615,8 @@
throws ActivationException, UnknownGroupException, RemoteException
{
checkShutdown();
- RegistryImpl.checkAccess
- ("ActivationSystem.getActivationGroupDesc");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
return getGroupEntry(id).desc;
}
@@ -588,7 +626,8 @@
* the activation daemon and exits the activation daemon.
*/
public void shutdown() throws AccessException {
- RegistryImpl.checkAccess("ActivationSystem.shutdown");
+ // RegistryImpl.checkAccess() is done in the SameHostOnlyServerRef
+ // during unmarshallCustomData and is not applicable to local access.
Object lock = startupLock;
if (lock != null) {
diff -r 8f1c0d565d13 -r 0e846618238e src/share/classes/sun/rmi/server/UnicastServerRef.java
--- a/src/share/classes/sun/rmi/server/UnicastServerRef.java Sat Jul 15 21:26:47 2017 +0100
+++ b/src/share/classes/sun/rmi/server/UnicastServerRef.java Sun Jul 16 00:29:10 2017 +0100
@@ -32,6 +32,7 @@
import java.io.ObjectStreamClass;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.rmi.AccessException;
import java.rmi.MarshalException;
import java.rmi.Remote;
import java.rmi.RemoteException;
@@ -290,20 +291,25 @@
try {
in = call.getInputStream();
num = in.readInt();
- if (num >= 0) {
- if (skel != null) {
- oldDispatch(obj, call, num);
- return;
- } else {
- throw new UnmarshalException(
- "skeleton class not found but required " +
- "for client version");
- }
+ } catch (Exception readEx) {
+ throw new UnmarshalException("error unmarshalling call header",
+ readEx);
+ }
+ if (num >= 0) {
+ if (skel != null) {
+ oldDispatch(obj, call, num);
+ return;
+ } else {
+ throw new UnmarshalException(
+ "skeleton class not found but required " +
+ "for client version");
}
+ }
+ try {
op = in.readLong();
} catch (Exception readEx) {
throw new UnmarshalException("error unmarshalling call header",
- readEx);
+ readEx);
}
/*
@@ -331,6 +337,11 @@
try {
unmarshalCustomCallData(in);
params = unmarshalParameters(obj, method, marshalStream);
+ } catch (AccessException aex) {
+ // For compatibility, AccessException is not wrapped in UnmarshalException
+ // disable saving any refs in the inputStream for GC
+ ((StreamRemoteCall) call).discardPendingRefs();
+ throw aex;
} catch (java.io.IOException | ClassNotFoundException e) {
// disable saving any refs in the inputStream for GC
((StreamRemoteCall) call).discardPendingRefs();
@@ -367,6 +378,7 @@
*/
}
} catch (Throwable e) {
+ Throwable origEx = e;
logCallException(e);
ObjectOutput out = call.getResultStream(false);
@@ -382,6 +394,12 @@
clearStackTraces(e);
}
out.writeObject(e);
+
+ // AccessExceptions should cause Transport.serviceCall
+ // to flag the connection as unusable.
+ if (origEx instanceof AccessException) {
+ throw new IOException("Connection is not reusable", origEx);
+ }
} finally {
call.releaseInputStream(); // in case skeleton doesn't
call.releaseOutputStream();
@@ -413,62 +431,41 @@
* Handle server-side dispatch using the RMI 1.1 stub/skeleton
* protocol, given a non-negative operation number that has
* already been read from the call stream.
+ * Exceptions are handled by the caller to be sent to the remote client.
*
* @param obj the target remote object for the call
* @param call the "remote call" from which operation and
* method arguments can be obtained.
* @param op the operation number
- * @exception IOException if unable to marshal return result or
+ * @throws Exception if unable to marshal return result or
* release input or output streams
*/
- public void oldDispatch(Remote obj, RemoteCall call, int op)
- throws IOException
+ private void oldDispatch(Remote obj, RemoteCall call, int op)
+ throws Exception
{
long hash; // hash for matching stub with skeleton
+ // read remote call header
+ ObjectInput in;
+ in = call.getInputStream();
try {
- // read remote call header
- ObjectInput in;
- try {
- in = call.getInputStream();
- try {
- Class> clazz = Class.forName("sun.rmi.transport.DGCImpl_Skel");
- if (clazz.isAssignableFrom(skel.getClass())) {
- ((MarshalInputStream)in).useCodebaseOnly();
- }
- } catch (ClassNotFoundException ignore) { }
- hash = in.readLong();
- } catch (Exception readEx) {
- throw new UnmarshalException("error unmarshalling call header",
- readEx);
+ Class> clazz = Class.forName("sun.rmi.transport.DGCImpl_Skel");
+ if (clazz.isAssignableFrom(skel.getClass())) {
+ ((MarshalInputStream)in).useCodebaseOnly();
}
+ } catch (ClassNotFoundException ignore) { }
- // if calls are being logged, write out object id and operation
- logCall(obj, skel.getOperations()[op]);
- unmarshalCustomCallData(in);
- // dispatch to skeleton for remote object
- skel.dispatch(obj, call, op, hash);
-
- } catch (Throwable e) {
- logCallException(e);
+ try {
+ hash = in.readLong();
+ } catch (Exception ioe) {
+ throw new UnmarshalException("error unmarshalling call header", ioe);
+ }
- ObjectOutput out = call.getResultStream(false);
- if (e instanceof Error) {
- e = new ServerError(
- "Error occurred in server thread", (Error) e);
- } else if (e instanceof RemoteException) {
- e = new ServerException(
- "RemoteException occurred in server thread",
- (Exception) e);
- }
- if (suppressStackTraces) {
- clearStackTraces(e);
- }
- out.writeObject(e);
- } finally {
- call.releaseInputStream(); // in case skeleton doesn't
- call.releaseOutputStream();
- }
+ // if calls are being logged, write out object id and operation
+ logCall(obj, skel.getOperations()[op]);
+ unmarshalCustomCallData(in);
+ // dispatch to skeleton for remote object
+ skel.dispatch(obj, call, op, hash);
}
/**