JDK-6178018 : UnicastRemoteObject.export() does not throw SecurityException in linux build
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.rmi
  • Affected Version: 5.0u1
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: solaris_9
  • CPU: sparc
  • Submitted: 2004-10-12
  • Updated: 2012-10-09
  • Resolved: 2004-10-18
Related Reports
Relates :  
Description
UnicastRemoteObject.export() does not throw SecurityException in Linux build if
the SecurityManager does not grant listen permission to the specified port.
See the following program:

import java.rmi.*;
import java.rmi.server.*;
import java.security.Permission;
import java.security.Permissions;
import java.net.SocketPermission;
import java.util.Enumeration;

public class UnicastTest {
    public static void main(String[] args) {
        Permissions perm = new Permissions();
        perm.add(new SocketPermission("127.0.0.1:3000", "listen"));
        System.setSecurityManager(new NoPermissionSM(perm));
         try {
              ExportImpl2 obj = new ExportImpl2();
              UnicastRemoteObject.exportObject(obj, 3000);
              System.out.println("SecurityException expected");
          } catch (SecurityException e) {
              System.out.println("OKAY");
          } catch (RemoteException e) {
               e.printStackTrace();
          }
      }
          
}

interface ExceptionRemote extends Remote {
}


class ExportImpl2 implements ExceptionRemote {
}

class NoPermissionSM extends SecurityManager {
    Permissions perms;
    /**
     * Construct a SecurityManager that will forbid all permissions
     * specified in perms.
     */
    public NoPermissionSM(Permissions perms) {
        this.perms = perms;
    }
    
    /** 
     * Construct a SecurityManager that will not forbid any
     * permission.
     */
    public NoPermissionSM() {
        this.perms = new Permissions();
    }

    /**
     *  Forbids actions which are specified in the constructor.
     *  @param p checked permission
     */
    public void checkPermission(Permission p) {
        for (Enumeration enum = perms.elements(); enum.hasMoreElements();) {
            Permission curPerm = (Permission) enum.nextElement();
            if (curPerm.implies(p)) {
                throw new SecurityException();             
            }
        }
    }
    
    /**
     *  Forbids actions which are specified in the constructor.
     *  @param p checked permission
     */
    public void checkPermission(Permission p, Object context) {

        for (Enumeration enum = perms.elements(); enum.hasMoreElements();) {
            Permission curPerm = (Permission) enum.nextElement();
            if (curPerm.implies(p)) {
                throw new SecurityException();
            }
        }
    }    
}

The output in latest Linux build is:

$ /java/re/j2se/1.5.0/promoted/latest/binaries/linux-i586/bin/java -classpath . UnicastTest
SecurityException expected

The output in latest Solaris build is:

$ /java/re/j2se/1.5/promoted/latest/binaries/solaris-sparc/bin/java -classpath . UnicastTest
OKAY
###@###.### 10/12/04 21:24 GMT

Comments
EVALUATION We'll need more information about the Linux machine on which this test case fails, because it works for me (prints "OKAY") on a nearby Linux machine (SuSE 9, kernel 2.4.21-99-default) with JDK 1.5.0 and 1.4.2. What is the operating system and kernel version? What are the contents of the /etc/hosts file? And any other information that might seem relevant. (A login to the machine would also be helpful, along with instructions for how to access JDK builds from it.) Also, it would be useful to know how the following smaller test case behaves on the same machine: import java.net.SocketPermission; import java.security.Permission; public class LocalHostImplies { public static void main(String[] args) throws Exception { Permission p1 = new SocketPermission("127.0.0.1:3000", "listen"); Permission p2 = new SocketPermission("localhost:3000", "listen"); System.out.println(p1.implies(p2)); } } If it outputs "false", that would narrow down the explanation of the failure of the original test case. ###@###.### 10/14/04 19:59 GMT Host information: Linux javathing 2.6.5-7.108-default #1 Wed Aug 25 13:34:40 UTC 2004 i686 i686 i386 GNU/Linux The machine can be assessed using the Sun login and LDAP password. Contents of /etc/hosts: =====begin==== 127.0.0.1 localhost # special IPv6 addresses ::1 localhost ipv6-localhost ipv6-loopback fe00::0 ipv6-localnet ff00::0 ipv6-mcastprefix ff02::1 ipv6-allnodes ff02::2 ipv6-allrouters ff02::3 ipv6-allhosts 10.5.29.70 javathing.sfbay.sun.comjavathing ====end===== Location of JDK builds and output of LocalHostImplies test: > /java/re/j2se/1.5.0/promoted/latest/binaries/linux-i586/bin/java -classpath /home/alwang/tests LocalHostImplies false ###@###.### 10/14/04 21:35 GMT Thanks-- I have reproduced the reported behavior on the Linux machine described above. If the primary concern is about whether invoking UnicastRemoteObject.exportObject requires the appropriate "listen" SocketPermission, then I don't think that the original test case demonstrates that it doesn't. If I comment out the following lines from UnicastTest.java: // Permissions perm = new Permissions(); // perm.add(new SocketPermission("127.0.0.1:3000", "listen")); // System.setSecurityManager(new NoPermissionSM(perm)); and run it with the following command: java -Djava.security.manager -Djava.security.policy==empty.security.policy UnicastTest where "empty.security.policy" is an empty file in the current directory, then the test passes (outputs "OKAY"). Note the == in the policy file setting-- this causes the JRE's default security policy, which grants "listen:1024-" SocketPermision to all code, to be ignored. Running the same command with -Djava.security.debug=access,failure shows the "listen" SocketPermission being checked. If that demonstration resolved the concern of this CR, then this CR can be closed. If there is remaining concern about why the original test case failed, I believe that it can be boiled down to why the above test LocalHostImplies outputs "false". Expanding that test slightly: import java.lang.reflect.Field; import java.net.InetAddress; import java.net.SocketPermission; import java.security.Permission; import java.util.Arrays; public class LocalHostImplies2 { public static void main(String[] args) throws Exception { SocketPermission p1 = new SocketPermission("127.0.0.1:3000", "listen"); System.out.println("p1: " + p1); System.out.println(" addresses: " + Arrays.asList(getAddresses(p1))); SocketPermission p2 = new SocketPermission("localhost:3000", "listen"); System.out.println("p2: " + p2); boolean result = p1.implies(p2); // force initialization of addresses System.out.println(" addresses: " + Arrays.asList(getAddresses(p2))); System.out.println("p1.implies(p2): " + result); } private static final Field addressesField; static { try { addressesField = SocketPermission.class.getDeclaredField("addresses"); } catch (NoSuchFieldException e) { throw new AssertionError(e); } addressesField.setAccessible(true); } private static InetAddress[] getAddresses(SocketPermission p) throws Exception { return (InetAddress[]) addressesField.get(p); } } it appears from the output of running this on the same Linux machine: p1: (java.net.SocketPermission 127.0.0.1:3000 listen,resolve) addresses: [/127.0.0.1] p2: (java.net.SocketPermission localhost:3000 listen,resolve) addresses: [localhost/0:0:0:0:0:0:0:1] p1.implies(p2): false that the reason is that when "localhost" in the second SocketPermission is resolved to IP addresses, it only resolves to the IPv6 loopback address, not the IPv4 one (127.0.0.1), which is what would match the first SocketPermission. I'm not quite sure why that happens, because running the following program: import java.net.InetAddress; import java.util.Arrays; public class LookupByName { public static void main(String[] args) throws Exception { System.out.println(Arrays.asList(InetAddress.getAllByName(args[0]))); } } on the same machine with "java LookupByName localhost" outputs a list of addresses that does include 127.0.0.1: [localhost/0:0:0:0:0:0:0:1, localhost/127.0.0.1] If the submitter would like to pursue this concern further, please transfer this CR to the java/classes_net category. ###@###.### 10/14/04 23:25 GMT New bug 6180108 is filed against java/classes_net. ###@###.### 10/15/04 22:07 GMT OK, there does not appear to be an RMI bug here, so I am closing this CR. ###@###.### 10/18/04 18:04 GMT
14-10-2004