changeset 8118:8a2b9d281caf

8055309: RMI needs better transportation considerations Reviewed-by: alanb, skoivu, msheppar
author igerasim
date Thu, 16 Oct 2014 22:49:04 +0400
parents 235491ff9df0
children ec3e1e179298
files src/share/classes/sun/rmi/transport/Transport.java src/share/classes/sun/rmi/transport/tcp/TCPTransport.java
diffstat 2 files changed, 58 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/rmi/transport/Transport.java	Wed Oct 15 10:37:07 2014 -0700
+++ b/src/share/classes/sun/rmi/transport/Transport.java	Thu Oct 16 22:49:04 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2014, 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
@@ -37,6 +37,10 @@
 import java.rmi.server.RemoteServer;
 import java.rmi.server.ServerNotActiveException;
 import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 import sun.rmi.runtime.Log;
 import sun.rmi.server.Dispatcher;
 import sun.rmi.server.UnicastServerRef;
@@ -67,6 +71,15 @@
     /** ObjID for DGCImpl */
     private static final ObjID dgcID = new ObjID(ObjID.DGC_ID);
 
+    /** AccessControlContext for setting context ClassLoader */
+    private static final AccessControlContext SETCCL_ACC;
+    static {
+        Permissions perms = new Permissions();
+        perms.add(new RuntimePermission("setContextClassLoader"));
+        ProtectionDomain[] pd = { new ProtectionDomain(null, perms) };
+        SETCCL_ACC = new AccessControlContext(pd);
+    }
+
     /**
      * Returns a <I>Channel</I> that generates connections to the
      * endpoint <I>ep</I>. A Channel is an object that creates and
@@ -116,6 +129,19 @@
     protected abstract void checkAcceptPermission(AccessControlContext acc);
 
     /**
+     * Sets the context class loader for the current thread.
+     */
+    private static void setContextClassLoader(final ClassLoader ccl) {
+        AccessController.doPrivileged(new PrivilegedAction<Void> () {
+                @Override
+                public Void run() {
+                    Thread.currentThread().setContextClassLoader(ccl);
+                    return null;
+                }
+            }, SETCCL_ACC);
+    }
+
+    /**
      * Service an incoming remote call. When a message arrives on the
      * connection indicating the beginning of a remote call, the
      * threads are required to call the <I>serviceCall</I> method of
@@ -163,11 +189,10 @@
                     target.getAccessControlContext();
                 ClassLoader ccl = target.getContextClassLoader();
 
-                Thread t = Thread.currentThread();
-                ClassLoader savedCcl = t.getContextClassLoader();
+                ClassLoader savedCcl = Thread.currentThread().getContextClassLoader();
 
                 try {
-                    t.setContextClassLoader(ccl);
+                    setContextClassLoader(ccl);
                     currentTransport.set(this);
                     try {
                         java.security.AccessController.doPrivileged(
@@ -182,7 +207,7 @@
                         throw (IOException) pae.getException();
                     }
                 } finally {
-                    t.setContextClassLoader(savedCcl);
+                    setContextClassLoader(savedCcl);
                     currentTransport.set(null);
                 }
 
--- a/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java	Wed Oct 15 10:37:07 2014 -0700
+++ b/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java	Thu Oct 16 22:49:04 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, 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
@@ -49,6 +49,9 @@
 import java.rmi.server.UID;
 import java.security.AccessControlContext;
 import java.security.AccessController;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
@@ -122,6 +125,14 @@
     private static final ThreadLocal<ConnectionHandler>
         threadConnectionHandler = new ThreadLocal<>();
 
+    /** an AccessControlContext with no permissions */
+    private static final AccessControlContext NOPERMS_ACC;
+    static {
+        Permissions perms = new Permissions();
+        ProtectionDomain[] pd = { new ProtectionDomain(null, perms) };
+        NOPERMS_ACC = new AccessControlContext(pd);
+    }
+
     /** endpoints for this transport */
     private final LinkedList<TCPEndpoint> epList;
     /** number of objects exported on this transport */
@@ -661,16 +672,22 @@
         }
 
         public void run() {
-            Thread t = Thread.currentThread();
-            String name = t.getName();
-            try {
-                t.setName("RMI TCP Connection(" +
-                          connectionCount.incrementAndGet() +
-                          ")-" + remoteHost);
-                run0();
-            } finally {
-                t.setName(name);
-            }
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    @Override
+                    public Void run() {
+                        Thread t = Thread.currentThread();
+                        String name = t.getName();
+                        try {
+                            t.setName("RMI TCP Connection(" +
+                                      connectionCount.incrementAndGet() +
+                                      ")-" + remoteHost);
+                            run0();
+                        } finally {
+                            t.setName(name);
+                        }
+                        return null;
+                    }
+                }, NOPERMS_ACC);
         }
 
         private void run0() {