--- a/src/java.base/share/classes/java/net/NetPermission.java Mon Oct 07 17:12:22 2019 +0200
+++ b/src/java.base/share/classes/java/net/NetPermission.java Mon Mar 25 17:15:27 2019 +0000
@@ -145,6 +145,15 @@
* </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>
+ *
+ * <tr>
* <th scope="row">specifyStreamHandler</th>
* <td>The ability
* to specify a stream handler when constructing a URL</td>
--- a/src/java.base/share/classes/java/net/ServerSocket.java Mon Oct 07 17:12:22 2019 +0200
+++ b/src/java.base/share/classes/java/net/ServerSocket.java Mon Mar 25 17:15:27 2019 +0000
@@ -32,6 +32,7 @@
import java.util.Set;
import java.util.Collections;
+import sun.security.util.SecurityConstants;
import sun.net.PlatformSocketImpl;
/**
@@ -73,13 +74,25 @@
*
* @throws NullPointerException if impl is {@code null}.
*
+ * @throws SecurityException if a security manager is set and
+ * its {@code checkPermission} method doesn't allow
+ * {@code NetPermission("setSocketImpl")}.
* @since 12
*/
protected ServerSocket(SocketImpl impl) {
Objects.requireNonNull(impl);
+ checkPermission();
this.impl = impl;
}
+ private static Void checkPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+ }
+ return null;
+ }
+
/**
* Creates an unbound server socket.
*
--- a/src/java.base/share/classes/java/net/Socket.java Mon Oct 07 17:12:22 2019 +0200
+++ b/src/java.base/share/classes/java/net/Socket.java Mon Mar 25 17:15:27 2019 +0000
@@ -25,6 +25,8 @@
package java.net;
+import sun.security.util.SecurityConstants;
+
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
@@ -182,12 +184,28 @@
*
* @throws 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 1.1
*/
protected Socket(SocketImpl impl) throws SocketException {
+ checkPermission(impl);
this.impl = impl;
}
+ 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.
--- a/src/java.base/share/classes/sun/security/util/SecurityConstants.java Mon Oct 07 17:12:22 2019 +0200
+++ b/src/java.base/share/classes/sun/security/util/SecurityConstants.java Mon Mar 25 17:15:27 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -97,6 +97,10 @@
public static final NetPermission GET_RESPONSECACHE_PERMISSION =
new NetPermission("getResponseCache");
+ // java.net.ServerSocket, java.net.Socket
+ public static final NetPermission SET_SOCKETIMPL_PERMISSION =
+ new NetPermission("setSocketImpl");
+
// java.lang.SecurityManager, sun.applet.AppletPanel
public static final RuntimePermission CREATE_CLASSLOADER_PERMISSION =
new RuntimePermission("createClassLoader");