8001318: Socket.getLocalAddress not consistent with InetAddress.getLocalHost
Reviewed-by: alanb, chegar, hawtin
--- a/jdk/src/share/classes/java/net/ServerSocket.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/net/ServerSocket.java Thu Mar 28 14:34:18 2013 -0700
@@ -390,15 +390,29 @@
* If the socket was bound prior to being {@link #close closed},
* then this method will continue to return the local address
* after the socket is closed.
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * the {@link InetAddress#getLoopbackAddress loopback} address is returned.
*
* @return the address to which this socket is bound,
- * or <code>null</code> if the socket is unbound.
+ * or the loopback address if denied by the security manager,
+ * or {@code null} if the socket is unbound.
+ *
+ * @see SecurityManager#checkConnect
*/
public InetAddress getInetAddress() {
if (!isBound())
return null;
try {
- return getImpl().getInetAddress();
+ InetAddress in = getImpl().getInetAddress();
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(in.getHostAddress(), -1);
+ return in;
+ } catch (SecurityException e) {
+ return InetAddress.getLoopbackAddress();
} catch (SocketException e) {
// nothing
// If we're bound, the impl has been created
@@ -431,18 +445,28 @@
}
/**
- * Returns the address of the endpoint this socket is bound to, or
- * <code>null</code> if it is not bound yet.
+ * Returns the address of the endpoint this socket is bound to.
* <p>
* If the socket was bound prior to being {@link #close closed},
* then this method will continue to return the address of the endpoint
* after the socket is closed.
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link InetAddress#getLoopbackAddress loopback} address and the local
+ * port to which the socket is bound is returned.
*
- * @return a <code>SocketAddress</code> representing the local endpoint of this
- * socket, or <code>null</code> if it is not bound yet.
+ * @return a {@code SocketAddress} representing the local endpoint of
+ * this socket, or a {@code SocketAddress} representing the
+ * loopback address if denied by the security manager,
+ * or {@code null} if the socket is not bound yet.
+ *
* @see #getInetAddress()
* @see #getLocalPort()
* @see #bind(SocketAddress)
+ * @see SecurityManager#checkConnect
* @since 1.4
*/
@@ -708,13 +732,25 @@
/**
* Returns the implementation address and implementation port of
* this socket as a <code>String</code>.
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * an {@code InetAddress} representing the
+ * {@link InetAddress#getLoopbackAddress loopback} address is returned as
+ * the implementation address.
*
* @return a string representation of this socket.
*/
public String toString() {
if (!isBound())
return "ServerSocket[unbound]";
- return "ServerSocket[addr=" + impl.getInetAddress() +
+ InetAddress in;
+ if (System.getSecurityManager() != null)
+ in = InetAddress.getLoopbackAddress();
+ else
+ in = impl.getInetAddress();
+ return "ServerSocket[addr=" + in +
",localport=" + impl.getLocalPort() + "]";
}
--- a/jdk/src/share/classes/java/net/Socket.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/net/Socket.java Thu Mar 28 14:34:18 2013 -0700
@@ -682,11 +682,18 @@
/**
* Gets the local address to which the socket is bound.
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * the {@link InetAddress#getLoopbackAddress loopback} address is returned.
*
- * @return the local address to which the socket is bound, or
- * the {@link InetAddress#isAnyLocalAddress wildcard} address
- * if the socket is closed or not bound yet.
+ * @return the local address to which the socket is bound,
+ * the loopback address if denied by the security manager, or
+ * the wildcard address if the socket is closed or not bound yet.
* @since JDK1.1
+ *
+ * @see SecurityManager#checkConnect
*/
public InetAddress getLocalAddress() {
// This is for backward compatibility
@@ -695,9 +702,14 @@
InetAddress in = null;
try {
in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkConnect(in.getHostAddress(), -1);
if (in.isAnyLocalAddress()) {
in = InetAddress.anyLocalAddress();
}
+ } catch (SecurityException e) {
+ in = InetAddress.getLoopbackAddress();
} catch (Exception e) {
in = InetAddress.anyLocalAddress(); // "0.0.0.0"
}
@@ -770,8 +782,7 @@
}
/**
- * Returns the address of the endpoint this socket is bound to, or
- * <code>null</code> if it is not bound yet.
+ * Returns the address of the endpoint this socket is bound to.
* <p>
* If a socket bound to an endpoint represented by an
* <code>InetSocketAddress </code> is {@link #close closed},
@@ -780,12 +791,23 @@
* <code>InetSocketAddress</code>'s address is the
* {@link InetAddress#isAnyLocalAddress wildcard} address
* and its port is the local port that it was bound to.
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link InetAddress#getLoopbackAddress loopback} address and the local
+ * port to which this socket is bound is returned.
*
- * @return a <code>SocketAddress</code> representing the local endpoint of this
- * socket, or <code>null</code> if it is not bound yet.
+ * @return a {@code SocketAddress} representing the local endpoint of
+ * this socket, or a {@code SocketAddress} representing the
+ * loopback address if denied by the security manager, or
+ * {@code null} if the socket is not bound yet.
+ *
* @see #getLocalAddress()
* @see #getLocalPort()
* @see #bind(SocketAddress)
+ * @see SecurityManager#checkConnect
* @since 1.4
*/
--- a/jdk/src/share/classes/java/net/SocksSocketImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/net/SocksSocketImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -28,6 +28,7 @@
import java.io.OutputStream;
import java.io.BufferedOutputStream;
import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import sun.net.SocksProxy;
import sun.net.www.ParseUtil;
@@ -590,7 +591,13 @@
/* Test for AnyLocal */
InetAddress naddr = baddr;
if (naddr.isAnyLocalAddress()) {
- naddr = cmdsock.getLocalAddress();
+ naddr = AccessController.doPrivileged(
+ new PrivilegedAction<InetAddress>() {
+ public InetAddress run() {
+ return cmdsock.getLocalAddress();
+
+ }
+ });
addr1 = naddr.getAddress();
}
out.write(PROTO_VERS4);
--- a/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousServerSocketChannel.java Thu Mar 28 14:34:18 2013 -0700
@@ -297,4 +297,25 @@
* If this channel's socket has not yet been bound
*/
public abstract Future<AsynchronousSocketChannel> accept();
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
}
--- a/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java Thu Mar 28 14:34:18 2013 -0700
@@ -645,4 +645,24 @@
TimeUnit unit,
A attachment,
CompletionHandler<Long,? super A> handler);
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ public abstract SocketAddress getLocalAddress() throws IOException;
}
--- a/jdk/src/share/classes/java/nio/channels/DatagramChannel.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/nio/channels/DatagramChannel.java Thu Mar 28 14:34:18 2013 -0700
@@ -565,4 +565,25 @@
return write(srcs, 0, srcs.length);
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+
}
--- a/jdk/src/share/classes/java/nio/channels/NetworkChannel.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/nio/channels/NetworkChannel.java Thu Mar 28 14:34:18 2013 -0700
@@ -87,8 +87,7 @@
NetworkChannel bind(SocketAddress local) throws IOException;
/**
- * Returns the socket address that this channel's socket is bound to, or
- * {@code null} if the socket is not bound.
+ * Returns the socket address that this channel's socket is bound to.
*
* <p> Where the channel is {@link #bind bound} to an Internet Protocol
* socket address then the return value from this method is of type {@link
--- a/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/nio/channels/ServerSocketChannel.java Thu Mar 28 14:34:18 2013 -0700
@@ -265,4 +265,25 @@
*/
public abstract SocketChannel accept() throws IOException;
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+
}
--- a/jdk/src/share/classes/java/nio/channels/SocketChannel.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/java/nio/channels/SocketChannel.java Thu Mar 28 14:34:18 2013 -0700
@@ -493,4 +493,25 @@
return write(srcs, 0, srcs.length);
}
+ /**
+ * {@inheritDoc}
+ * <p>
+ * If there is a security manager set, its {@code checkConnect} method is
+ * called with the local address and {@code -1} as its arguments to see
+ * if the operation is allowed. If the operation is not allowed,
+ * a {@code SocketAddress} representing the
+ * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+ * local port of the channel's socket is returned.
+ *
+ * @return The {@code SocketAddress} that the socket is bound to, or the
+ * {@code SocketAddress} representing the loopback address if
+ * denied by the security manager, or {@code null} if the
+ * channel's socket is not bound
+ *
+ * @throws ClosedChannelException {@inheritDoc}
+ * @throws IOException {@inheritDoc}
+ */
+ @Override
+ public abstract SocketAddress getLocalAddress() throws IOException;
+
}
--- a/jdk/src/share/classes/sun/net/NetworkClient.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/net/NetworkClient.java Thu Mar 28 14:34:18 2013 -0700
@@ -200,7 +200,13 @@
protected InetAddress getLocalAddress() throws IOException {
if (serverSocket == null)
throw new IOException("not connected");
- return serverSocket.getLocalAddress();
+ return AccessController.doPrivileged(
+ new PrivilegedAction<InetAddress>() {
+ public InetAddress run() {
+ return serverSocket.getLocalAddress();
+
+ }
+ });
}
/** Close an open connection to the server. */
--- a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java Thu Mar 28 14:34:18 2013 -0700
@@ -76,7 +76,10 @@
private FtpReplyCode lastReplyCode = null;
/** Welcome message from the server, if any. */
private String welcomeMsg;
- private boolean passiveMode = true;
+ /**
+ * Only passive mode used in JDK. See Bug 8010784.
+ */
+ private final boolean passiveMode = true;
private TransferType type = TransferType.BINARY;
private long restartOffset = 0;
private long lastTransSize = -1; // -1 means 'unknown size'
@@ -645,9 +648,18 @@
} else {
s = new Socket();
}
+
+ InetAddress serverAddress = AccessController.doPrivileged(
+ new PrivilegedAction<InetAddress>() {
+ @Override
+ public InetAddress run() {
+ return server.getLocalAddress();
+ }
+ });
+
// Bind the socket to the same address as the control channel. This
// is needed in case of multi-homed systems.
- s.bind(new InetSocketAddress(server.getLocalAddress(), 0));
+ s.bind(new InetSocketAddress(serverAddress, 0));
if (connectTimeout >= 0) {
s.connect(dest, connectTimeout);
} else {
@@ -816,7 +828,9 @@
* @see #setActiveMode()
*/
public sun.net.ftp.FtpClient enablePassiveMode(boolean passive) {
- passiveMode = passive;
+
+ // Only passive mode used in JDK. See Bug 8010784.
+ // passiveMode = passive;
return this;
}
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -34,6 +34,8 @@
import java.util.logging.Level;
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import sun.net.httpserver.HttpConnection.State;
/**
@@ -244,7 +246,14 @@
}
public InetSocketAddress getAddress() {
- return (InetSocketAddress)schan.socket().getLocalSocketAddress();
+ return AccessController.doPrivileged(
+ new PrivilegedAction<InetSocketAddress>() {
+ public InetSocketAddress run() {
+ return
+ (InetSocketAddress)schan.socket()
+ .getLocalSocketAddress();
+ }
+ });
}
Selector getSelector () {
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -51,7 +51,7 @@
protected final FileDescriptor fd;
// the local address to which the channel's socket is bound
- protected volatile SocketAddress localAddress = null;
+ protected volatile InetSocketAddress localAddress = null;
// need this lock to set local address
private final Object stateLock = new Object();
@@ -173,7 +173,7 @@
public final SocketAddress getLocalAddress() throws IOException {
if (!isOpen())
throw new ClosedChannelException();
- return localAddress;
+ return Net.getRevealedLocalAddress(localAddress);
}
@Override
@@ -251,7 +251,7 @@
if (localAddress == null) {
sb.append("unbound");
} else {
- sb.append(localAddress.toString());
+ sb.append(Net.getRevealedLocalAddressAsString(localAddress));
}
}
sb.append(']');
--- a/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -53,8 +53,8 @@
// protects state, localAddress, and remoteAddress
protected final Object stateLock = new Object();
- protected volatile SocketAddress localAddress = null;
- protected volatile SocketAddress remoteAddress = null;
+ protected volatile InetSocketAddress localAddress = null;
+ protected volatile InetSocketAddress remoteAddress = null;
// State, increases monotonically
static final int ST_UNINITIALIZED = -1;
@@ -442,7 +442,7 @@
public final SocketAddress getLocalAddress() throws IOException {
if (!isOpen())
throw new ClosedChannelException();
- return localAddress;
+ return Net.getRevealedLocalAddress(localAddress);
}
@Override
@@ -582,7 +582,8 @@
}
if (localAddress != null) {
sb.append(" local=");
- sb.append(localAddress.toString());
+ sb.append(
+ Net.getRevealedLocalAddressAsString(localAddress));
}
if (remoteAddress != null) {
sb.append(" remote=");
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -85,8 +85,8 @@
private int state = ST_UNINITIALIZED;
// Binding
- private SocketAddress localAddress;
- private SocketAddress remoteAddress;
+ private InetSocketAddress localAddress;
+ private InetSocketAddress remoteAddress;
// Our socket adaptor, if any
private DatagramSocket socket;
@@ -168,7 +168,8 @@
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
- return localAddress;
+ // Perform security check before returning address
+ return Net.getRevealedLocalAddress(localAddress);
}
}
@@ -721,6 +722,7 @@
}
}
+ @Override
public DatagramChannel connect(SocketAddress sa) throws IOException {
int localPort = 0;
@@ -742,7 +744,7 @@
// Connection succeeded; disallow further invocation
state = ST_CONNECTED;
- remoteAddress = sa;
+ remoteAddress = isa;
sender = isa;
cachedSenderInetAddress = isa.getAddress();
cachedSenderPort = isa.getPort();
@@ -761,7 +763,7 @@
synchronized (stateLock) {
if (!isConnected() || !isOpen())
return this;
- InetSocketAddress isa = (InetSocketAddress)remoteAddress;
+ InetSocketAddress isa = remoteAddress;
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkConnect(isa.getAddress().getHostAddress(),
--- a/jdk/src/share/classes/sun/nio/ch/Net.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/Net.java Thu Mar 28 14:34:18 2013 -0700
@@ -31,6 +31,7 @@
import java.util.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
public class Net {
@@ -183,6 +184,34 @@
}
/**
+ * Returns the local address after performing a SecurityManager#checkConnect.
+ */
+ static InetSocketAddress getRevealedLocalAddress(InetSocketAddress addr) {
+ SecurityManager sm = System.getSecurityManager();
+ if (addr == null || sm == null)
+ return addr;
+
+ try{
+ sm.checkConnect(addr.getAddress().getHostAddress(), -1);
+ // Security check passed
+ } catch (SecurityException e) {
+ // Return loopback address only if security check fails
+ addr = getLoopbackAddress(addr.getPort());
+ }
+ return addr;
+ }
+
+ static String getRevealedLocalAddressAsString(InetSocketAddress addr) {
+ return System.getSecurityManager() == null ? addr.toString() :
+ getLoopbackAddress(addr.getPort()).toString();
+ }
+
+ private static InetSocketAddress getLoopbackAddress(int port) {
+ return new InetSocketAddress(InetAddress.getLoopbackAddress(),
+ port);
+ }
+
+ /**
* Returns any IPv4 address of the given network interface, or
* null if the interface does not have any IPv4 addresses.
*/
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketAdaptor.java Thu Mar 28 14:34:18 2013 -0700
@@ -80,7 +80,8 @@
public InetAddress getInetAddress() {
if (!ssc.isBound())
return null;
- return Net.asInetSocketAddress(ssc.localAddress()).getAddress();
+ return Net.getRevealedLocalAddress(ssc.localAddress()).getAddress();
+
}
public int getLocalPort() {
--- a/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/ServerSocketChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -72,7 +72,7 @@
private int state = ST_UNINITIALIZED;
// Binding
- private SocketAddress localAddress; // null => unbound
+ private InetSocketAddress localAddress; // null => unbound
// set true when exclusive binding is on and SO_REUSEADDR is emulated
private boolean isReuseAddress;
@@ -116,7 +116,9 @@
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
- return localAddress;
+ return localAddress == null ? localAddress
+ : Net.getRevealedLocalAddress(
+ Net.asInetSocketAddress(localAddress));
}
}
@@ -190,7 +192,7 @@
}
}
- public SocketAddress localAddress() {
+ public InetSocketAddress localAddress() {
synchronized (stateLock) {
return localAddress;
}
@@ -384,14 +386,15 @@
StringBuffer sb = new StringBuffer();
sb.append(this.getClass().getName());
sb.append('[');
- if (!isOpen())
+ if (!isOpen()) {
sb.append("closed");
- else {
+ } else {
synchronized (stateLock) {
- if (localAddress() == null) {
+ InetSocketAddress addr = localAddress();
+ if (addr == null) {
sb.append("unbound");
} else {
- sb.append(localAddress().toString());
+ sb.append(Net.getRevealedLocalAddressAsString(addr));
}
}
}
--- a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java Thu Mar 28 14:34:18 2013 -0700
@@ -149,9 +149,10 @@
public InetAddress getLocalAddress() {
if (sc.isOpen()) {
- SocketAddress local = sc.localAddress();
- if (local != null)
- return ((InetSocketAddress)local).getAddress();
+ InetSocketAddress local = sc.localAddress();
+ if (local != null) {
+ return Net.getRevealedLocalAddress(local).getAddress();
+ }
}
return new InetSocketAddress(0).getAddress();
}
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -83,8 +83,8 @@
private int state = ST_UNINITIALIZED;
// Binding
- private SocketAddress localAddress;
- private SocketAddress remoteAddress;
+ private InetSocketAddress localAddress;
+ private InetSocketAddress remoteAddress;
// Input/Output open
private boolean isInputOpen = true;
@@ -146,7 +146,7 @@
synchronized (stateLock) {
if (!isOpen())
throw new ClosedChannelException();
- return localAddress;
+ return Net.getRevealedLocalAddress(localAddress);
}
}
@@ -547,7 +547,7 @@
IOUtil.configureBlocking(fd, block);
}
- public SocketAddress localAddress() {
+ public InetSocketAddress localAddress() {
synchronized (stateLock) {
return localAddress;
}
@@ -974,6 +974,7 @@
return fdVal;
}
+ @Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append(this.getClass().getSuperclass().getName());
@@ -997,9 +998,10 @@
sb.append(" oshut");
break;
}
- if (localAddress() != null) {
+ InetSocketAddress addr = localAddress();
+ if (addr != null) {
sb.append(" local=");
- sb.append(localAddress().toString());
+ sb.append(Net.getRevealedLocalAddressAsString(addr));
}
if (remoteAddress() != null) {
sb.append(" remote=");
--- a/jdk/src/share/classes/sun/rmi/server/Activation.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/rmi/server/Activation.java Thu Mar 28 14:34:18 2013 -0700
@@ -2230,7 +2230,13 @@
}
public InetAddress getInetAddress() {
- return serverSocket.getInetAddress();
+ return AccessController.doPrivileged(
+ new PrivilegedAction<InetAddress>() {
+ @Override
+ public InetAddress run() {
+ return serverSocket.getInetAddress();
+ }
+ });
}
public int getLocalPort() {
@@ -2238,7 +2244,13 @@
}
public SocketAddress getLocalSocketAddress() {
- return serverSocket.getLocalSocketAddress();
+ return AccessController.doPrivileged(
+ new PrivilegedAction<SocketAddress>() {
+ @Override
+ public SocketAddress run() {
+ return serverSocket.getLocalSocketAddress();
+ }
+ });
}
/**
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/WrappedSocket.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/WrappedSocket.java Thu Mar 28 14:34:18 2013 -0700
@@ -28,6 +28,8 @@
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
/**
* The WrappedSocket class provides a general wrapper for providing an
@@ -78,7 +80,14 @@
* Get the local address to which the socket is bound.
*/
public InetAddress getLocalAddress() {
- return socket.getLocalAddress();
+ return AccessController.doPrivileged(
+ new PrivilegedAction<InetAddress>() {
+ @Override
+ public InetAddress run() {
+ return socket.getLocalAddress();
+
+ }
+ });
}
/**
--- a/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/solaris/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -241,7 +241,7 @@
synchronized (stateLock) {
state = ST_CONNECTED;
localAddress = Net.localAddress(fd);
- remoteAddress = pendingRemote;
+ remoteAddress = (InetSocketAddress)pendingRemote;
}
}
--- a/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpNet.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/solaris/classes/sun/nio/ch/sctp/SctpNet.java Thu Mar 28 14:34:18 2013 -0700
@@ -94,18 +94,44 @@
static Set<SocketAddress> getLocalAddresses(int fd)
throws IOException {
- HashSet<SocketAddress> set = null;
+ Set<SocketAddress> set = null;
SocketAddress[] saa = getLocalAddresses0(fd);
if (saa != null) {
- set = new HashSet<SocketAddress>(saa.length);
- for (SocketAddress sa : saa)
- set.add(sa);
+ set = getRevealedLocalAddressSet(saa);
}
return set;
}
+ private static Set<SocketAddress> getRevealedLocalAddressSet(
+ SocketAddress[] saa)
+ {
+ SecurityManager sm = System.getSecurityManager();
+ Set<SocketAddress> set = new HashSet<>(saa.length);
+ for (SocketAddress sa : saa) {
+ set.add(getRevealedLocalAddress(sa, sm));
+ }
+ return set;
+ }
+
+ private static SocketAddress getRevealedLocalAddress(SocketAddress sa,
+ SecurityManager sm)
+ {
+ if (sm == null || sa == null)
+ return sa;
+ InetSocketAddress ia = (InetSocketAddress)sa;
+ try{
+ sm.checkConnect(ia.getAddress().getHostAddress(), -1);
+ // Security check passed
+ } catch (SecurityException e) {
+ // Return loopback address
+ return new InetSocketAddress(InetAddress.getLoopbackAddress(),
+ ia.getPort());
+ }
+ return sa;
+ }
+
static Set<SocketAddress> getRemoteAddresses(int fd, int assocId)
throws IOException {
HashSet<SocketAddress> set = null;
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Thu Mar 28 06:55:42 2013 -0400
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java Thu Mar 28 14:34:18 2013 -0700
@@ -137,7 +137,9 @@
// invoked by WindowsAsynchronousServerSocketChannelImpl when new connection
// accept
- void setConnected(SocketAddress localAddress, SocketAddress remoteAddress) {
+ void setConnected(InetSocketAddress localAddress,
+ InetSocketAddress remoteAddress)
+ {
synchronized (stateLock) {
state = ST_CONNECTED;
this.localAddress = localAddress;