diff options
Diffstat (limited to 'src/share/classes/java/net')
-rw-r--r-- | src/share/classes/java/net/NetPermission.java | 11 | ||||
-rw-r--r-- | src/share/classes/java/net/ServerSocket.java | 15 | ||||
-rw-r--r-- | src/share/classes/java/net/Socket.java | 18 | ||||
-rw-r--r-- | src/share/classes/java/net/SocksSocketImpl.java | 10 | ||||
-rw-r--r-- | src/share/classes/java/net/URL.java | 32 | ||||
-rw-r--r-- | src/share/classes/java/net/URLStreamHandler.java | 7 |
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); |