From d7402c700b010ec8d04375b25e1acb7bd593b238 Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Wed, 2 Dec 2009 12:17:42 +0000 Subject: [PATCH] 6893954: Subclasses of InetAddress may incorrectly interpret network addresses Runtime type checks and deserialization check Reviewed-by: chegar, alanb, jccollet --- .../classes/java/net/DatagramSocket.java | 19 ++++++++-- .../share/classes/java/net/InetAddress.java | 18 +++++++++ .../classes/java/net/MulticastSocket.java | 6 +++ .../classes/java/net/NetworkInterface.java | 6 ++- jdk/src/share/classes/java/net/Socket.java | 38 +++++++++++++------ jdk/src/share/classes/sun/nio/ch/Net.java | 3 ++ 6 files changed, 74 insertions(+), 16 deletions(-) diff --git a/jdk/src/share/classes/java/net/DatagramSocket.java b/jdk/src/share/classes/java/net/DatagramSocket.java index 40c95ef5aee..3e3464c677d 100644 --- a/jdk/src/share/classes/java/net/DatagramSocket.java +++ b/jdk/src/share/classes/java/net/DatagramSocket.java @@ -118,6 +118,7 @@ class DatagramSocket implements java.io.Closeable { if (address == null) { throw new IllegalArgumentException("connect: null address"); } + checkAddress (address, "connect"); if (isClosed()) return; SecurityManager security = System.getSecurityManager(); @@ -363,13 +364,15 @@ class DatagramSocket implements java.io.Closeable { 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 @@ class DatagramSocket implements java.io.Closeable { 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 @@ class DatagramSocket implements java.io.Closeable { 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(); diff --git a/jdk/src/share/classes/java/net/InetAddress.java b/jdk/src/share/classes/java/net/InetAddress.java index 21f257ebcf3..f0ef1cacdc1 100644 --- a/jdk/src/share/classes/java/net/InetAddress.java +++ b/jdk/src/share/classes/java/net/InetAddress.java @@ -35,6 +35,7 @@ import java.util.ArrayList; 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 @@ class InetAddress implements java.io.Serializable { 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"); + } + } } /* diff --git a/jdk/src/share/classes/java/net/MulticastSocket.java b/jdk/src/share/classes/java/net/MulticastSocket.java index f6ba1c47f2f..483fc7e3ede 100644 --- a/jdk/src/share/classes/java/net/MulticastSocket.java +++ b/jdk/src/share/classes/java/net/MulticastSocket.java @@ -289,6 +289,7 @@ class MulticastSocket extends DatagramSocket { throw new SocketException("Socket is closed"); } + checkAddress(mcastaddr, "joinGroup"); SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(mcastaddr); @@ -323,6 +324,7 @@ class MulticastSocket extends DatagramSocket { throw new SocketException("Socket is closed"); } + checkAddress(mcastaddr, "leaveGroup"); SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkMulticast(mcastaddr); @@ -370,6 +372,7 @@ class MulticastSocket extends DatagramSocket { 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 @@ class MulticastSocket extends DatagramSocket { 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 @@ class MulticastSocket extends DatagramSocket { 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 @@ class MulticastSocket extends DatagramSocket { throws IOException { if (isClosed()) throw new SocketException("Socket is closed"); + checkAddress(p.getAddress(), "send"); synchronized(ttlLock) { synchronized(p) { if (connectState == ST_NOT_CONNECTED) { diff --git a/jdk/src/share/classes/java/net/NetworkInterface.java b/jdk/src/share/classes/java/net/NetworkInterface.java index da9503d573b..07941b062fd 100644 --- a/jdk/src/share/classes/java/net/NetworkInterface.java +++ b/jdk/src/share/classes/java/net/NetworkInterface.java @@ -290,8 +290,12 @@ public final class NetworkInterface { * If the specified address is null. */ 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); } diff --git a/jdk/src/share/classes/java/net/Socket.java b/jdk/src/share/classes/java/net/Socket.java index 39dfebd4180..032f4e0e93b 100644 --- a/jdk/src/share/classes/java/net/Socket.java +++ b/jdk/src/share/classes/java/net/Socket.java @@ -122,6 +122,9 @@ class Socket implements java.io.Closeable { 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 @@ class Socket implements java.io.Closeable { 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 @@ class Socket implements java.io.Closeable { 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 @@ class Socket implements java.io.Closeable { 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. */ diff --git a/jdk/src/share/classes/sun/nio/ch/Net.java b/jdk/src/share/classes/sun/nio/ch/Net.java index f910c5db05e..405b0541c93 100644 --- a/jdk/src/share/classes/sun/nio/ch/Net.java +++ b/jdk/src/share/classes/sun/nio/ch/Net.java @@ -68,6 +68,9 @@ class Net { // package-private 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; }