aboutsummaryrefslogtreecommitdiff
path: root/src/share/classes/java/net
diff options
context:
space:
mode:
Diffstat (limited to 'src/share/classes/java/net')
-rw-r--r--src/share/classes/java/net/NetPermission.java11
-rw-r--r--src/share/classes/java/net/ServerSocket.java15
-rw-r--r--src/share/classes/java/net/Socket.java18
-rw-r--r--src/share/classes/java/net/SocksSocketImpl.java10
-rw-r--r--src/share/classes/java/net/URL.java32
-rw-r--r--src/share/classes/java/net/URLStreamHandler.java7
6 files changed, 84 insertions, 9 deletions
diff --git a/src/share/classes/java/net/NetPermission.java b/src/share/classes/java/net/NetPermission.java
index 9178f34872..2cda1bcdad 100644
--- a/src/share/classes/java/net/NetPermission.java
+++ b/src/share/classes/java/net/NetPermission.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -151,6 +151,15 @@ have access to. Thus it might be able to trick the system into
creating a ProtectionDomain/CodeSource for a class even though
that class really didn't come from that location.</td>
* </tr>
+ *
+ * <tr>
+ * <th scope="row">setSocketImpl</th>
+ * <td>The ability to create a sub-class of Socket or ServerSocket with a
+ * user specified SocketImpl.</td>
+ * <td>Malicious user-defined SocketImpls can change the behavior of
+ * Socket and ServerSocket in surprising ways, by virtue of their
+ * ability to access the protected fields of SocketImpl.</td>
+ * </tr>
* </table>
*
* @see java.security.BasicPermission
diff --git a/src/share/classes/java/net/ServerSocket.java b/src/share/classes/java/net/ServerSocket.java
index 2ee3420d54..6dd0496223 100644
--- a/src/share/classes/java/net/ServerSocket.java
+++ b/src/share/classes/java/net/ServerSocket.java
@@ -31,6 +31,8 @@ import java.nio.channels.ServerSocketChannel;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
+import sun.security.util.SecurityConstants;
+
/**
* This class implements server sockets. A server socket waits for
* requests to come in over the network. It performs some operation
@@ -71,12 +73,25 @@ class ServerSocket implements java.io.Closeable {
/**
* Package-private constructor to create a ServerSocket associated with
* the given SocketImpl.
+ *
+ * @throws SecurityException if a security manager is set and
+ * its {@code checkPermission} method doesn't allow
+ * {@code NetPermission("setSocketImpl")}.
*/
ServerSocket(SocketImpl impl) {
+ checkPermission();
this.impl = impl;
impl.setServerSocket(this);
}
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ return null;
+ }
+
/**
* Creates an unbound server socket.
*
diff --git a/src/share/classes/java/net/Socket.java b/src/share/classes/java/net/Socket.java
index ff841fc0fb..eed64378b5 100644
--- a/src/share/classes/java/net/Socket.java
+++ b/src/share/classes/java/net/Socket.java
@@ -25,6 +25,8 @@
package java.net;
+import sun.security.util.SecurityConstants;
+
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
@@ -159,9 +161,14 @@ class Socket implements java.io.Closeable {
*
* @exception SocketException if there is an error in the underlying protocol,
* such as a TCP error.
+ *
+ * @throws SecurityException if {@code impl} is non-null and a security manager is set
+ * and its {@code checkPermission} method doesn't allow {@code NetPermission("setSocketImpl")}.
+ *
* @since JDK1.1
*/
protected Socket(SocketImpl impl) throws SocketException {
+ checkPermission(impl);
this.impl = impl;
if (impl != null) {
checkOldImpl();
@@ -169,6 +176,17 @@ class Socket implements java.io.Closeable {
}
}
+ private static Void checkPermission(SocketImpl impl) {
+ if (impl == null) {
+ return null;
+ }
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ return null;
+ }
+
/**
* Creates a stream socket and connects it to the specified port
* number on the named host.
diff --git a/src/share/classes/java/net/SocksSocketImpl.java b/src/share/classes/java/net/SocksSocketImpl.java
index dd89283fbd..3d162ec829 100644
--- a/src/share/classes/java/net/SocksSocketImpl.java
+++ b/src/share/classes/java/net/SocksSocketImpl.java
@@ -118,7 +118,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
private int readSocksReply(InputStream in, byte[] data, long deadlineMillis) throws IOException {
int len = data.length;
int received = 0;
- for (int attempts = 0; received < len && attempts < 3; attempts++) {
+ while (received < len) {
int count;
try {
count = ((SocketInputStream)in).read(data, received, len - received, remainingMillis(deadlineMillis));
@@ -520,7 +520,11 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
throw new SocketException("Reply from SOCKS server badly formatted");
break;
case DOMAIN_NAME:
- len = data[1];
+ byte[] lenByte = new byte[1];
+ i = readSocksReply(in, lenByte, deadlineMillis);
+ if (i != 1)
+ throw new SocketException("Reply from SOCKS server badly formatted");
+ len = lenByte[0] & 0xFF;
byte[] host = new byte[len];
i = readSocksReply(in, host, deadlineMillis);
if (i != len)
@@ -531,7 +535,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
throw new SocketException("Reply from SOCKS server badly formatted");
break;
case IPV6:
- len = data[1];
+ len = 16;
addr = new byte[len];
i = readSocksReply(in, addr, deadlineMillis);
if (i != len)
diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java
index 919825adbb..bbe87b6272 100644
--- a/src/share/classes/java/net/URL.java
+++ b/src/share/classes/java/net/URL.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@ import java.io.ObjectStreamField;
import java.io.ObjectInputStream.GetField;
import java.util.Hashtable;
import java.util.StringTokenizer;
+import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants;
/**
@@ -414,13 +415,29 @@ public final class URL implements java.io.Serializable {
}
ref = parts.getRef();
- // Note: we don't do validation of the URL here. Too risky to change
+ // Note: we don't do full validation of the URL here. Too risky to change
// right now, but worth considering for future reference. -br
if (handler == null &&
(handler = getURLStreamHandler(protocol)) == null) {
throw new MalformedURLException("unknown protocol: " + protocol);
}
this.handler = handler;
+ if (host != null && isBuiltinStreamHandler(handler)) {
+ String s = IPAddressUtil.checkExternalForm(this);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
+ }
+ if ("jar".equalsIgnoreCase(protocol)) {
+ if (handler instanceof sun.net.www.protocol.jar.Handler) {
+ // URL.openConnection() would throw a confusing exception
+ // so generate a better exception here instead.
+ String s = ((sun.net.www.protocol.jar.Handler) handler).checkNestedProtocol(file);
+ if (s != null) {
+ throw new MalformedURLException(s);
+ }
+ }
+ }
}
/**
@@ -943,7 +960,12 @@ public final class URL implements java.io.Serializable {
* @since 1.5
*/
public URI toURI() throws URISyntaxException {
- return new URI (toString());
+ URI uri = new URI(toString());
+ if (authority != null && isBuiltinStreamHandler(handler)) {
+ String s = IPAddressUtil.checkAuthority(this);
+ if (s != null) throw new URISyntaxException(authority, s);
+ }
+ return uri;
}
/**
@@ -1400,6 +1422,10 @@ public final class URL implements java.io.Serializable {
return replacementURL;
}
+ boolean isBuiltinStreamHandler(URLStreamHandler handler) {
+ return isBuiltinStreamHandler(handler.getClass().getName());
+ }
+
private boolean isBuiltinStreamHandler(String handlerClassName) {
return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
}
diff --git a/src/share/classes/java/net/URLStreamHandler.java b/src/share/classes/java/net/URLStreamHandler.java
index 513055982c..cbdf02a5ee 100644
--- a/src/share/classes/java/net/URLStreamHandler.java
+++ b/src/share/classes/java/net/URLStreamHandler.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -532,12 +532,15 @@ public abstract class URLStreamHandler {
* @see java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
* @since 1.3
*/
- protected void setURL(URL u, String protocol, String host, int port,
+ protected void setURL(URL u, String protocol, String host, int port,
String authority, String userInfo, String path,
String query, String ref) {
if (this != u.handler) {
throw new SecurityException("handler for url different from " +
"this handler");
+ } else if (host != null && u.isBuiltinStreamHandler(this)) {
+ String s = IPAddressUtil.checkHostString(host);
+ if (s != null) throw new IllegalArgumentException(s);
}
// ensure that no one can reset the protocol on a given URL.
u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);