JDK-6533031 : Non-clear semantics of "localhost" for SocketPermission
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 6
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • OS: linux
  • CPU: x86
  • Submitted: 2007-03-09
  • Updated: 2011-03-17
Related Reports
Relates :  
Relates :  
Description
Both description of java.netSocketPermission class and  "Java Security Architecture" document
introduce notion of "localhost" which can be passed to SocketPermission constructor as name of affected host.

However it is not clear what this term means in case of host with several network interfaces - either several NICs, or one NIC with both IPv4 and IPv6 setup. Yet it may be virtual network interface (when PPP or VPN is used).

There are two options of interpretation:

1. All network interfaces on current host
2. Network interface returned by InetAddress.getLocalHost()

Let's note that java.net.DatagramSocket allows to bind socket to any local interface. At the same time SecurityManager.checkListen() method invoked to check permission to listen uses just parameter port of type int. It may implicitly mean that "localhost" means all network interfaces (at least for "listen" action).

However in other parts of API spec meaning of term "local host" is different. For instance, in specification of java.net.InetAddress.getLocalHost() method "local host" means single interface assuming that one of several present ones is selected.

So precise meaning of specifying permission for "localhost" is non-clear.

Comments
EVALUATION Agreed, we need to clarify that doc a bit. Will do that for jdk 7.
27-03-2007

EVALUATION I've looked at sources and performed some experiments and it looks like "localhost" means all local interfaces just for "listen" action: 1. SocketPermission.implies() method used private method getIP() which just invokes getAllByName0 which looks like just inteface to native name resolution service. No special handling for "localhost" word is provided here. So for implies method "localhost" means "address to while localhost name is resolved" (which is usually loopback interface), not all network interfaces. 2. "listen" is separate case because java.lang.SecurityManager.checkListen(int port) method does not depend on host by it's design. Moreover, it seems for me that for "listen" action host name is just placeholder so any String means "any network interface" (however last statement is not double checked by me) I've performed following experiment on my host with followiong network configuration: rez2@fisher:~/work/sun/CDC/samples> /sbin/ifconfig eth0 Link encap:Ethernet HWaddr 00:11:2F:AA:E3:3E inet addr:129.159.125.172 Bcast:129.159.125.255 Mask:255.255.254.0 inet6 addr: fe80::211:2fff:feaa:e33e/64 Scope:Link UP BROADCAST NOTRAILERS RUNNING MULTICAST MTU:1500 Metric:1 RX packets:9664169 errors:0 dropped:0 overruns:0 frame:0 TX packets:3382780 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1898797140 (1810.8 Mb) TX bytes:917580869 (875.0 Mb) Interrupt:209 Memory:fcefc000-0 lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:151832447 errors:0 dropped:0 overruns:0 frame:0 TX packets:151832447 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:901716787 (859.9 Mb) TX bytes:901716787 (859.9 Mb) Apache web server is listening on port 80 and there is follwoing Java application: import java.net.*; public class SC { public static void main(String[] args) throws Exception { Socket s = new Socket(args[0], 80); System.out.println("s: " + s); } } When started without any security manager it successfully connects to port 80: rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java SC 127.0.0.1 s: Socket[addr=/127.0.0.1,port=80,localport=42976] rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java SC ::1 s: Socket[addr=/0:0:0:0:0:0:0:1,port=80,localport=42979] rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java SC 129.159.125.172 s: Socket[addr=/129.159.125.172,port=80,localport=42982] rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java SC fe80::211:2fff:feaa:e33e s: Socket[addr=/fe80:0:0:0:211:2fff:feaa:e33e,port=80,localport=42985] Then I've tried to start it with security manager installed and with following java.policy file: grant { permission java.net.SocketPermission "localhost:80", "connect"; }; If "localhost" would mean "any local network interface" then results would be the same. However: rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java -Djava.security.manager -Djava.security.policy==java.policy SC 127.0.0.1 s: Socket[addr=/127.0.0.1,port=80,localport=42988] rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java -Djava.security.manager -Djava.security.policy==java.policy SC ::1 Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission [0:0:0:0:0:0:0:1]:80 connect,resolve) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkConnect(SecurityManager.java:1034) at java.net.Socket.connect(Socket.java:513) at java.net.Socket.connect(Socket.java:469) at java.net.Socket.<init>(Socket.java:366) at java.net.Socket.<init>(Socket.java:179) at SC.main(SC.java:6) rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java -Djava.security.manager -Djava.security.policy==java.policy SC 129.159.125.172 Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission 129.159.125.172:80 connect,resolve) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkConnect(SecurityManager.java:1034) at java.net.Socket.connect(Socket.java:513) at java.net.Socket.connect(Socket.java:469) at java.net.Socket.<init>(Socket.java:366) at java.net.Socket.<init>(Socket.java:179) at SC.main(SC.java:6) rez2@fisher:~/work/sun/CDC/samples> /opt/jdk1.6.0/bin/java -Djava.security.manager -Djava.security.policy==java.policy SC fe80::211:2fff:feaa:e33e Exception in thread "main" java.security.AccessControlException: access denied (java.net.SocketPermission [fe80:0:0:0:211:2fff:feaa:e33e]:80 connect,resolve) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkConnect(SecurityManager.java:1034) at java.net.Socket.connect(Socket.java:513) at java.net.Socket.connect(Socket.java:469) at java.net.Socket.<init>(Socket.java:366) at java.net.Socket.<init>(Socket.java:179) at SC.main(SC.java:6) BTW, may be such interpretation is reasonable however it looks confusing and sound be explicictly clarified that meaning of "localhost" for "listen" is not the same as for other action. It extremely needed with current syntax when it is possible to use one hostname with several actions separated by comma. Otherwise it is non-obvious that in SocketPermission("localhost:-1", "accept,listen,connect"); semantics of "localhost" is depends on action.
15-03-2007

EVALUATION As far as SocketPermission is concerned, "localhost" does include all the interfaces of the local machine. However, as pointed, there is some ambiguity with the use of that term here and there. Will clarify for jdk7.
14-03-2007