6893954: Subclasses of InetAddress may incorrectly interpret network addresses
Summary: runtime type checks and deserialization check
Reviewed-by: chegar, alanb, jccollet
--- 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;
}