6893954: Subclasses of InetAddress may incorrectly interpret network addresses
authormichaelm
Wed, 02 Dec 2009 12:17:42 +0000
changeset 5180 8161f879d704
parent 5179 c619a34cb99b
child 5181 44105be1276a
6893954: Subclasses of InetAddress may incorrectly interpret network addresses Summary: runtime type checks and deserialization check Reviewed-by: chegar, alanb, jccollet
jdk/src/share/classes/java/net/DatagramSocket.java
jdk/src/share/classes/java/net/InetAddress.java
jdk/src/share/classes/java/net/MulticastSocket.java
jdk/src/share/classes/java/net/NetworkInterface.java
jdk/src/share/classes/java/net/Socket.java
jdk/src/share/classes/sun/nio/ch/Net.java
--- a/jdk/src/share/classes/java/net/DatagramSocket.java	Tue Dec 01 08:55:15 2009 -0800
+++ b/jdk/src/share/classes/java/net/DatagramSocket.java	Wed Dec 02 12:17:42 2009 +0000
@@ -118,6 +118,7 @@
         if (address == null) {
             throw new IllegalArgumentException("connect: null address");
         }
+        checkAddress (address, "connect");
         if (isClosed())
             return;
         SecurityManager security = System.getSecurityManager();
@@ -363,13 +364,15 @@
         InetSocketAddress epoint = (InetSocketAddress) addr;
         if (epoint.isUnresolved())
             throw new SocketException("Unresolved address");
+        InetAddress iaddr = epoint.getAddress();
+        int port = epoint.getPort();
+        checkAddress(iaddr, "bind");
         SecurityManager sec = System.getSecurityManager();
         if (sec != null) {
-            sec.checkListen(epoint.getPort());
+            sec.checkListen(port);
         }
         try {
-            getImpl().bind(epoint.getPort(),
-                           epoint.getAddress());
+            getImpl().bind(port, iaddr);
         } catch (SocketException e) {
             getImpl().close();
             throw e;
@@ -377,6 +380,15 @@
         bound = true;
     }
 
+    void checkAddress (InetAddress addr, String op) {
+        if (addr == null) {
+            return;
+        }
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
+            throw new IllegalArgumentException(op + ": invalid address type");
+        }
+    }
+
     /**
      * Connects the socket to a remote address for this socket. When a
      * socket is connected to a remote address, packets may only be
@@ -603,6 +615,7 @@
         synchronized (p) {
             if (isClosed())
                 throw new SocketException("Socket is closed");
+            checkAddress (p.getAddress(), "send");
             if (connectState == ST_NOT_CONNECTED) {
                 // check the address is ok wiht the security manager on every send.
                 SecurityManager security = System.getSecurityManager();
--- a/jdk/src/share/classes/java/net/InetAddress.java	Tue Dec 01 08:55:15 2009 -0800
+++ b/jdk/src/share/classes/java/net/InetAddress.java	Wed Dec 02 12:17:42 2009 +0000
@@ -35,6 +35,7 @@
 import java.security.AccessController;
 import java.io.ObjectStreamException;
 import java.io.IOException;
+import java.io.ObjectInputStream;
 import sun.security.action.*;
 import sun.net.InetAddressCachePolicy;
 import sun.net.util.IPAddressUtil;
@@ -1472,6 +1473,23 @@
 
         return impl;
     }
+
+    private void readObjectNoData (ObjectInputStream s) throws
+                         IOException, ClassNotFoundException {
+        if (getClass().getClassLoader() != null) {
+            throw new SecurityException ("invalid address type");
+        }
+    }
+
+    private void readObject (ObjectInputStream s) throws
+                         IOException, ClassNotFoundException {
+        s.defaultReadObject ();
+        if (getClass().getClassLoader() != null) {
+            hostName = null;
+            address = 0;
+            throw new SecurityException ("invalid address type");
+        }
+    }
 }
 
 /*
--- a/jdk/src/share/classes/java/net/MulticastSocket.java	Tue Dec 01 08:55:15 2009 -0800
+++ b/jdk/src/share/classes/java/net/MulticastSocket.java	Wed Dec 02 12:17:42 2009 +0000
@@ -289,6 +289,7 @@
             throw new SocketException("Socket is closed");
         }
 
+        checkAddress(mcastaddr, "joinGroup");
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkMulticast(mcastaddr);
@@ -323,6 +324,7 @@
             throw new SocketException("Socket is closed");
         }
 
+        checkAddress(mcastaddr, "leaveGroup");
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkMulticast(mcastaddr);
@@ -370,6 +372,7 @@
         if (oldImpl)
             throw new UnsupportedOperationException();
 
+        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
@@ -416,6 +419,7 @@
         if (oldImpl)
             throw new UnsupportedOperationException();
 
+        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
@@ -441,6 +445,7 @@
         if (isClosed()) {
             throw new SocketException("Socket is closed");
         }
+        checkAddress(inf, "setInterface");
         synchronized (infLock) {
             getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
             infAddress = inf;
@@ -632,6 +637,7 @@
         throws IOException {
             if (isClosed())
                 throw new SocketException("Socket is closed");
+            checkAddress(p.getAddress(), "send");
             synchronized(ttlLock) {
                 synchronized(p) {
                     if (connectState == ST_NOT_CONNECTED) {
--- a/jdk/src/share/classes/java/net/NetworkInterface.java	Tue Dec 01 08:55:15 2009 -0800
+++ b/jdk/src/share/classes/java/net/NetworkInterface.java	Wed Dec 02 12:17:42 2009 +0000
@@ -290,8 +290,12 @@
      *          If the specified address is <tt>null</tt>.
      */
     public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {
-        if (addr == null)
+        if (addr == null) {
             throw new NullPointerException();
+        }
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
+            throw new IllegalArgumentException ("invalid address type");
+        }
         return getByInetAddress0(addr);
     }
 
--- a/jdk/src/share/classes/java/net/Socket.java	Tue Dec 01 08:55:15 2009 -0800
+++ b/jdk/src/share/classes/java/net/Socket.java	Wed Dec 02 12:17:42 2009 +0000
@@ -122,6 +122,9 @@
         if (p.type() == Proxy.Type.SOCKS) {
             SecurityManager security = System.getSecurityManager();
             InetSocketAddress epoint = (InetSocketAddress) p.address();
+            if (epoint.getAddress() != null) {
+                checkAddress (epoint.getAddress(), "Socket");
+            }
             if (security != null) {
                 if (epoint.isUnresolved())
                     security.checkConnect(epoint.getHostName(),
@@ -558,15 +561,16 @@
             throw new IllegalArgumentException("Unsupported address type");
 
         InetSocketAddress epoint = (InetSocketAddress) endpoint;
+        InetAddress addr = epoint.getAddress ();
+        int port = epoint.getPort();
+        checkAddress(addr, "connect");
 
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             if (epoint.isUnresolved())
-                security.checkConnect(epoint.getHostName(),
-                                      epoint.getPort());
+                security.checkConnect(epoint.getHostName(), port);
             else
-                security.checkConnect(epoint.getAddress().getHostAddress(),
-                                      epoint.getPort());
+                security.checkConnect(addr.getHostAddress(), port);
         }
         if (!created)
             createImpl(true);
@@ -574,10 +578,9 @@
             impl.connect(epoint, timeout);
         else if (timeout == 0) {
             if (epoint.isUnresolved())
-                impl.connect(epoint.getAddress().getHostName(),
-                             epoint.getPort());
+                impl.connect(addr.getHostName(), port);
             else
-                impl.connect(epoint.getAddress(), epoint.getPort());
+                impl.connect(addr, port);
         } else
             throw new UnsupportedOperationException("SocketImpl.connect(addr, timeout)");
         connected = true;
@@ -614,14 +617,25 @@
         InetSocketAddress epoint = (InetSocketAddress) bindpoint;
         if (epoint != null && epoint.isUnresolved())
             throw new SocketException("Unresolved address");
-        if (bindpoint == null)
-            getImpl().bind(InetAddress.anyLocalAddress(), 0);
-        else
-            getImpl().bind(epoint.getAddress(),
-                           epoint.getPort());
+        if (epoint == null) {
+            epoint = new InetSocketAddress(0);
+        }
+        InetAddress addr = epoint.getAddress();
+        int port = epoint.getPort();
+        checkAddress (addr, "bind");
+        getImpl().bind (addr, port);
         bound = true;
     }
 
+    private void checkAddress (InetAddress addr, String op) {
+        if (addr == null) {
+            return;
+        }
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
+            throw new IllegalArgumentException(op + ": invalid address type");
+        }
+    }
+
     /**
      * set the flags after an accept() call.
      */
--- a/jdk/src/share/classes/sun/nio/ch/Net.java	Tue Dec 01 08:55:15 2009 -0800
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java	Wed Dec 02 12:17:42 2009 +0000
@@ -68,6 +68,9 @@
         InetSocketAddress isa = (InetSocketAddress)sa;
         if (isa.isUnresolved())
             throw new UnresolvedAddressException(); // ## needs arg
+        InetAddress addr = isa.getAddress();
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address))
+            throw new IllegalArgumentException("Invalid address type");
         return isa;
     }