diff -r da71aa13f86b -r 06d7236d6ef6 src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java Thu Jul 18 07:25:17 2019 -0700 +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java Thu Jan 17 10:44:17 2019 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2019, 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 @@ -25,16 +25,17 @@ package sun.rmi.transport; +import sun.rmi.transport.tcp.TCPConnection; + +import java.io.IOException; import java.io.ObjectInputFilter; -import java.io.ObjectInputStream; +import java.rmi.RemoteException; import java.rmi.dgc.Lease; import java.rmi.dgc.VMID; import java.rmi.server.UID; import java.security.AccessController; import java.security.PrivilegedAction; - -import sun.rmi.server.UnicastRef; -import sun.rmi.transport.tcp.TCPConnection; +import java.util.ArrayList; /** * Stubs to invoke DGC remote methods. @@ -72,7 +73,9 @@ public void clean(java.rmi.server.ObjID[] $param_arrayOf_ObjID_1, long $param_long_2, java.rmi.dgc.VMID $param_VMID_3, boolean $param_boolean_4) throws java.rmi.RemoteException { try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash); + StreamRemoteCall call = (StreamRemoteCall)ref.newCall((java.rmi.server.RemoteObject) this, + operations, 0, interfaceHash); + call.setObjectInputFilter(DGCImpl_Stub::leaseFilter); try { java.io.ObjectOutput out = call.getOutputStream(); out.writeObject($param_arrayOf_ObjID_1); @@ -97,7 +100,10 @@ public java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[] $param_arrayOf_ObjID_1, long $param_long_2, java.rmi.dgc.Lease $param_Lease_3) throws java.rmi.RemoteException { try { - java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash); + StreamRemoteCall call = + (StreamRemoteCall)ref.newCall((java.rmi.server.RemoteObject) this, + operations, 1, interfaceHash); + call.setObjectInputFilter(DGCImpl_Stub::leaseFilter); try { java.io.ObjectOutput out = call.getOutputStream(); out.writeObject($param_arrayOf_ObjID_1); @@ -108,26 +114,16 @@ } ref.invoke(call); java.rmi.dgc.Lease $result; - Connection connection = ((StreamRemoteCall) call).getConnection(); + Connection connection = call.getConnection(); try { java.io.ObjectInput in = call.getInputStream(); - - if (in instanceof ObjectInputStream) { - /** - * Set a filter on the stream for the return value. - */ - ObjectInputStream ois = (ObjectInputStream) in; - AccessController.doPrivileged((PrivilegedAction)() -> { - ois.setObjectInputFilter(DGCImpl_Stub::leaseFilter); - return null; - }); - } $result = (java.rmi.dgc.Lease) in.readObject(); - } catch (java.io.IOException | java.lang.ClassNotFoundException e) { + } catch (ClassCastException | IOException | ClassNotFoundException e) { if (connection instanceof TCPConnection) { // Modified to prevent re-use of the connection after an exception ((TCPConnection) connection).getChannel().free(connection, false); } + call.discardPendingRefs(); throw new java.rmi.UnmarshalException("error unmarshalling return", e); } finally { ref.done(call); @@ -146,6 +142,11 @@ * ObjectInputFilter to filter DGCClient return value (a Lease). * The list of acceptable classes is very short and explicit. * The depth and array sizes are limited. + *

+ * The filter must accept normal and exception returns. + * A DGC server may throw exceptions that may have a cause + * and suppressed exceptions. + * Only exceptions in {@code java.base} and {@code java.rmi} are allowed. * * @param filterInfo access to class, arrayLength, etc. * @return {@link ObjectInputFilter.Status#ALLOWED} if allowed, @@ -172,7 +173,14 @@ } return (clazz == UID.class || clazz == VMID.class || - clazz == Lease.class) + clazz == Lease.class || + (Throwable.class.isAssignableFrom(clazz) && + (Object.class.getModule() == clazz.getModule() || + RemoteException.class.getModule() == clazz.getModule())) || + clazz == StackTraceElement.class || + clazz == ArrayList.class || // for suppressed exceptions, if any + clazz == Object.class || + clazz.getName().equals("java.util.Collections$EmptyList")) ? ObjectInputFilter.Status.ALLOWED : ObjectInputFilter.Status.REJECTED; }