diff --git a/src/share/classes/com/sun/nio/sctp/SctpChannel.java b/src/share/classes/com/sun/nio/sctp/SctpChannel.java
index 52709b07e9d3c58b50a2d049519e603c33be1ea8..130390c260b62b54a5e46429f3af2ad6594b3b59 100644
--- a/src/share/classes/com/sun/nio/sctp/SctpChannel.java
+++ b/src/share/classes/com/sun/nio/sctp/SctpChannel.java
@@ -276,6 +276,11 @@ public abstract class SctpChannel
*
* @throws IOException
* If some other I/O error occurs
+ *
+ * @throws SecurityException
+ * If a security manager has been installed and its
+ * {@link SecurityManager#checkListen checkListen} method denies
+ * the operation
*/
public abstract SctpChannel bind(SocketAddress local)
throws IOException;
diff --git a/src/share/classes/java/lang/SecurityManager.java b/src/share/classes/java/lang/SecurityManager.java
index 635f6db093e26e84cc51dc0cf17019b488dd492d..aedd0a134dcaef3b2ac09a331a7357ee61de9c5e 100644
--- a/src/share/classes/java/lang/SecurityManager.java
+++ b/src/share/classes/java/lang/SecurityManager.java
@@ -1114,11 +1114,8 @@ class SecurityManager {
* calling thread is not allowed to wait for a connection request on
* the specified local port number.
*
- * If port is not 0, this method calls
- * checkPermission
with the
+ * This method calls checkPermission
with the
* SocketPermission("localhost:"+port,"listen")
.
- * If port is zero, this method calls checkPermission
- * with SocketPermission("localhost:1024-","listen").
*
* If you override this method, then you should make a call to
* super.checkListen
@@ -1131,12 +1128,8 @@ class SecurityManager {
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkListen(int port) {
- if (port == 0) {
- checkPermission(SecurityConstants.LOCAL_LISTEN_PERMISSION);
- } else {
- checkPermission(new SocketPermission("localhost:"+port,
- SecurityConstants.SOCKET_LISTEN_ACTION));
- }
+ checkPermission(new SocketPermission("localhost:"+port,
+ SecurityConstants.SOCKET_LISTEN_ACTION));
}
/**
diff --git a/src/share/classes/java/net/Socket.java b/src/share/classes/java/net/Socket.java
index 21cf5aae1330e9f25fe0e2c70ffc6d07a4fc7f23..dedc8ca1b856b9c152e3a9bc118c0bd3c97cf97f 100644
--- a/src/share/classes/java/net/Socket.java
+++ b/src/share/classes/java/net/Socket.java
@@ -272,7 +272,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its
- * {@code checkConnect} method doesn't allow the operation.
+ * {@code checkConnect} method doesn't allow the connection
+ * to the destination, or if its {@code checkListen} method
+ * doesn't allow the bind to the local port.
* @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
@@ -311,7 +313,9 @@ class Socket implements java.io.Closeable {
* {@code zero} for a system selected free port.
* @exception IOException if an I/O error occurs when creating the socket.
* @exception SecurityException if a security manager exists and its
- * {@code checkConnect} method doesn't allow the operation.
+ * {@code checkConnect} method doesn't allow the connection
+ * to the destination, or if its {@code checkListen} method
+ * doesn't allow the bind to the local port.
* @exception IllegalArgumentException if the port parameter or localPort
* parameter is outside the specified range of valid port values,
* which is between 0 and 65535, inclusive.
@@ -609,6 +613,9 @@ class Socket implements java.io.Closeable {
* is already bound.
* @throws IllegalArgumentException if bindpoint is a
* SocketAddress subclass not supported by this socket
+ * @throws SecurityException if a security manager exists and its
+ * {@code checkListen} method doesn't allow the bind
+ * to the local port.
*
* @since 1.4
* @see #isBound
@@ -630,6 +637,10 @@ class Socket implements java.io.Closeable {
InetAddress addr = epoint.getAddress();
int port = epoint.getPort();
checkAddress (addr, "bind");
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkListen(port);
+ }
getImpl().bind (addr, port);
bound = true;
}
diff --git a/src/share/classes/java/net/SocketPermission.java b/src/share/classes/java/net/SocketPermission.java
index 1b11437b1aa0e6cacd72465f886639d85d2a77d3..88f8a5a486115891fa31a9940cb72cff2a2af1ce 100644
--- a/src/share/classes/java/net/SocketPermission.java
+++ b/src/share/classes/java/net/SocketPermission.java
@@ -34,6 +34,9 @@ import java.util.StringTokenizer;
import java.net.InetAddress;
import java.security.Permission;
import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.AccessController;
+import java.security.Security;
import java.io.Serializable;
import java.io.ObjectStreamField;
import java.io.ObjectOutputStream;
@@ -89,6 +92,9 @@ import sun.security.util.Debug;
* form "N-", where N is a port number, signifies all ports
* numbered N and above, while a specification of the
* form "-N" indicates all ports numbered N and below.
+ * The special port value {@code 0} refers to the entire ephemeral
+ * port range. This is a fixed range of ports a system may use to
+ * allocate dynamic ports from. The actual range may be system dependent.
*
* The possible ways to connect to the host are
*
@@ -97,7 +103,8 @@ import sun.security.util.Debug;
* listen
* resolve
*
- * The "listen" action is only meaningful when used with "localhost".
+ * The "listen" action is only meaningful when used with "localhost" and
+ * means the ability to bind to a specified port.
* The "resolve" action is implied when any of the other actions are present.
* The action "resolve" refers to host/ip name service lookups.
*
@@ -176,6 +183,7 @@ public final class SocketPermission extends Permission
private static final int PORT_MIN = 0;
private static final int PORT_MAX = 65535;
private static final int PRIV_PORT_MAX = 1023;
+ private static final int DEF_EPH_LOW = 49152;
// the actions mask
private transient int mask;
@@ -226,6 +234,14 @@ public final class SocketPermission extends Permission
private static Debug debug = null;
private static boolean debugInit = false;
+ // ephemeral port range for this system
+ private static final int ephemeralLow = initEphemeralPorts(
+ "low", DEF_EPH_LOW
+ );
+ private static final int ephemeralHigh = initEphemeralPorts(
+ "high", PORT_MAX
+ );
+
static {
Boolean tmp = java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction("sun.net.trustNameService"));
@@ -359,6 +375,14 @@ public final class SocketPermission extends Permission
}
}
+ /**
+ * Returns true if the permission has specified zero
+ * as its value (or lower bound) signifying the ephemeral range
+ */
+ private boolean includesEphemerals() {
+ return portrange[0] == 0;
+ }
+
/**
* Initialize the SocketPermission object. We don't do any DNS lookups
* as this point, instead we hold off until the implies method is
@@ -850,10 +874,21 @@ public final class SocketPermission extends Permission
int i,j;
if ((that.mask & RESOLVE) != that.mask) {
- // check port range
+
+ // check simple port range
if ((that.portrange[0] < this.portrange[0]) ||
(that.portrange[1] > this.portrange[1])) {
+
+ // if either includes the ephemeral range, do full check
+ if (this.includesEphemerals() || that.includesEphemerals()) {
+ if (!inRange(this.portrange[0], this.portrange[1],
+ that.portrange[0], that.portrange[1]))
+ {
+ return false;
+ }
+ } else {
return false;
+ }
}
}
@@ -1168,6 +1203,83 @@ public final class SocketPermission extends Permission
init(getName(),getMask(actions));
}
+ /**
+ * Check the system/security property for the ephemeral port range
+ * for this system. The suffix is either "high" or "low"
+ */
+ private static int initEphemeralPorts(String suffix, int defval) {
+ return AccessController.doPrivileged(
+ new PrivilegedAction(){
+ public Integer run() {
+ int val = Integer.getInteger(
+ "jdk.net.ephemeralPortRange."+suffix, -1
+ );
+ if (val != -1) {
+ return val;
+ } else {
+ String prop = Security.getProperty(
+ "network.ephemeralPortRange."+suffix
+ );
+ try {
+ val = Integer.parseInt(prop);
+ } catch (NumberFormatException e) {
+ // shouldn't happen
+ return defval;
+ }
+ }
+ return val;
+ }
+ }
+ );
+ }
+
+ /**
+ * Check if the target range is within the policy range
+ * together with the ephemeral range for this platform
+ * (if policy includes ephemeral range)
+ */
+ private static boolean inRange(
+ int policyLow, int policyHigh, int targetLow, int targetHigh
+ )
+ {
+ if (targetLow == 0) {
+ // check policy includes ephemeral range
+ if (!inRange(policyLow, policyHigh, ephemeralLow, ephemeralHigh)) {
+ return false;
+ }
+ if (targetHigh == 0) {
+ // nothing left to do
+ return true;
+ }
+ // continue check with first real port number
+ targetLow = 1;
+ }
+
+ if (policyLow == 0 && policyHigh == 0) {
+ // ephemeral range only
+ return targetLow >= ephemeralLow && targetHigh <= ephemeralHigh;
+ }
+
+ if (policyLow != 0) {
+ // simple check of policy only
+ return targetLow >= policyLow && targetHigh <= policyHigh;
+ }
+
+ // policyLow == 0 which means possibly two ranges to check
+
+ // first check if policy and ephem range overlap/contiguous
+
+ if (policyHigh >= ephemeralLow - 1) {
+ return targetHigh <= ephemeralHigh;
+ }
+
+ // policy and ephem range do not overlap
+
+ // target range must lie entirely inside policy range or eph range
+
+ return (targetLow <= policyHigh && targetHigh <= policyHigh) ||
+ (targetLow >= ephemeralLow && targetHigh <= ephemeralHigh);
+ }
/*
public String toString()
{
diff --git a/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java b/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java
index 2c2a1a306d5bf5fab5a4c4d52ba970d3dea43256..2b9fd885ae1a8a40710e6a15deaa5ba0d3355602 100644
--- a/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java
+++ b/src/share/classes/java/nio/channels/AsynchronousSocketChannel.java
@@ -200,6 +200,10 @@ public abstract class AsynchronousSocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * If a security manager has been installed and its
+ * {@link SecurityManager#checkListen checkListen} method denies
+ * the operation
*/
@Override
public abstract AsynchronousSocketChannel bind(SocketAddress local)
diff --git a/src/share/classes/java/nio/channels/SocketChannel.java b/src/share/classes/java/nio/channels/SocketChannel.java
index 091570cbf6424ab31464e1dd77a86d9ac56ebcf4..2864643e6a102ba70357751cb1947f13dafbdfed 100644
--- a/src/share/classes/java/nio/channels/SocketChannel.java
+++ b/src/share/classes/java/nio/channels/SocketChannel.java
@@ -227,6 +227,10 @@ public abstract class SocketChannel
* @throws UnsupportedAddressTypeException {@inheritDoc}
* @throws ClosedChannelException {@inheritDoc}
* @throws IOException {@inheritDoc}
+ * @throws SecurityException
+ * If a security manager has been installed and its
+ * {@link SecurityManager#checkListen checkListen} method denies
+ * the operation
*
* @since 1.7
*/
diff --git a/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
index 273f9def315a7fd866d1f61dd99257db2fb42675..5aaf4a5ffbe957b2ffc01c0aedba554d758aecbd 100644
--- a/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
+++ b/src/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java
@@ -428,6 +428,10 @@ abstract class AsynchronousSocketChannelImpl
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkListen(isa.getPort());
+ }
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
diff --git a/src/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/share/classes/sun/nio/ch/SocketChannelImpl.java
index 806168392e935c980ed1d5ad6622f6d232e8cebd..28f3fc0c3be9aa4f71b29298a5b7df87f90e4dfa 100644
--- a/src/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/src/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -572,6 +572,10 @@ class SocketChannelImpl
throw new AlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkListen(isa.getPort());
+ }
NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort());
Net.bind(fd, isa.getAddress(), isa.getPort());
localAddress = Net.localAddress(fd);
diff --git a/src/share/classes/sun/rmi/registry/RegistryImpl.java b/src/share/classes/sun/rmi/registry/RegistryImpl.java
index 0b01116cdacc876690d49c431107f54965635c70..8ddbe5cf3bfcbc0435b75c0aad7dd404489dc33d 100644
--- a/src/share/classes/sun/rmi/registry/RegistryImpl.java
+++ b/src/share/classes/sun/rmi/registry/RegistryImpl.java
@@ -94,8 +94,23 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
RMIServerSocketFactory ssf)
throws RemoteException
{
- LiveRef lref = new LiveRef(id, port, csf, ssf);
- setup(new UnicastServerRef2(lref));
+ if (port == Registry.REGISTRY_PORT && System.getSecurityManager() != null) {
+ // grant permission for default port only.
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction() {
+ public Void run() throws RemoteException {
+ LiveRef lref = new LiveRef(id, port, csf, ssf);
+ setup(new UnicastServerRef2(lref));
+ return null;
+ }
+ }, null, new SocketPermission("localhost:"+port, "listen,accept"));
+ } catch (PrivilegedActionException pae) {
+ throw (RemoteException)pae.getException();
+ }
+ } else {
+ LiveRef lref = new LiveRef(id, port, csf, ssf);
+ setup(new UnicastServerRef2(lref));
+ }
}
/**
@@ -352,7 +367,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
public RegistryImpl run() throws RemoteException {
return new RegistryImpl(regPort);
}
- }, getAccessControlContext());
+ }, getAccessControlContext(regPort));
} catch (PrivilegedActionException ex) {
throw (RemoteException) ex.getException();
}
@@ -382,7 +397,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* The approach used here is taken from the similar method
* getAccessControlContext() in the sun.applet.AppletPanel class.
*/
- private static AccessControlContext getAccessControlContext() {
+ private static AccessControlContext getAccessControlContext(int port) {
// begin with permissions granted to all code in current policy
PermissionCollection perms = AccessController.doPrivileged(
new java.security.PrivilegedAction() {
@@ -404,6 +419,7 @@ public class RegistryImpl extends java.rmi.server.RemoteServer
* related classes themselves are more tightly limited by RMI.
*/
perms.add(new SocketPermission("*", "connect,accept"));
+ perms.add(new SocketPermission("localhost:"+port, "listen,accept"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvmstat.*"));
perms.add(new RuntimePermission("accessClassInPackage.sun.jvm.hotspot.*"));
diff --git a/src/share/classes/sun/security/util/SecurityConstants.java b/src/share/classes/sun/security/util/SecurityConstants.java
index 2b985ad0f65c8016bb7f6424a3523df48473b043..fbcd88301e39339ba9337969e33e2a2ba73e4788 100644
--- a/src/share/classes/sun/security/util/SecurityConstants.java
+++ b/src/share/classes/sun/security/util/SecurityConstants.java
@@ -222,5 +222,5 @@ public final class SecurityConstants {
// java.lang.SecurityManager
public static final SocketPermission LOCAL_LISTEN_PERMISSION =
- new SocketPermission("localhost:1024-", SOCKET_LISTEN_ACTION);
+ new SocketPermission("localhost:0", SOCKET_LISTEN_ACTION);
}
diff --git a/src/share/lib/security/java.policy b/src/share/lib/security/java.policy
index 3312bdf92f2135c5fe0e137a4cd07d6fc06258f5..120694d699336bce208cb1328581bfbfdc5cc905 100644
--- a/src/share/lib/security/java.policy
+++ b/src/share/lib/security/java.policy
@@ -2,48 +2,48 @@
// Standard extensions get all permissions by default
grant codeBase "file:${{java.ext.dirs}}/*" {
- permission java.security.AllPermission;
+ permission java.security.AllPermission;
};
// default permissions granted to all domains
-grant {
- // Allows any thread to stop itself using the java.lang.Thread.stop()
- // method that takes no argument.
- // Note that this permission is granted by default only to remain
- // backwards compatible.
- // It is strongly recommended that you either remove this permission
- // from this policy file or further restrict it to code sources
- // that you specify, because Thread.stop() is potentially unsafe.
- // See the API specification of java.lang.Thread.stop() for more
+grant {
+ // Allows any thread to stop itself using the java.lang.Thread.stop()
+ // method that takes no argument.
+ // Note that this permission is granted by default only to remain
+ // backwards compatible.
+ // It is strongly recommended that you either remove this permission
+ // from this policy file or further restrict it to code sources
+ // that you specify, because Thread.stop() is potentially unsafe.
+ // See the API specification of java.lang.Thread.stop() for more
// information.
- permission java.lang.RuntimePermission "stopThread";
-
- // allows anyone to listen on un-privileged ports
- permission java.net.SocketPermission "localhost:1024-", "listen";
-
- // "standard" properies that can be read by anyone
-
- permission java.util.PropertyPermission "java.version", "read";
- permission java.util.PropertyPermission "java.vendor", "read";
- permission java.util.PropertyPermission "java.vendor.url", "read";
- permission java.util.PropertyPermission "java.class.version", "read";
- permission java.util.PropertyPermission "os.name", "read";
- permission java.util.PropertyPermission "os.version", "read";
- permission java.util.PropertyPermission "os.arch", "read";
- permission java.util.PropertyPermission "file.separator", "read";
- permission java.util.PropertyPermission "path.separator", "read";
- permission java.util.PropertyPermission "line.separator", "read";
-
- permission java.util.PropertyPermission "java.specification.version", "read";
- permission java.util.PropertyPermission "java.specification.vendor", "read";
- permission java.util.PropertyPermission "java.specification.name", "read";
-
- permission java.util.PropertyPermission "java.vm.specification.version", "read";
- permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
- permission java.util.PropertyPermission "java.vm.specification.name", "read";
- permission java.util.PropertyPermission "java.vm.version", "read";
- permission java.util.PropertyPermission "java.vm.vendor", "read";
- permission java.util.PropertyPermission "java.vm.name", "read";
+ permission java.lang.RuntimePermission "stopThread";
+
+ // allows anyone to listen on dynamic ports
+ permission java.net.SocketPermission "localhost:0", "listen";
+
+ // "standard" properies that can be read by anyone
+
+ permission java.util.PropertyPermission "java.version", "read";
+ permission java.util.PropertyPermission "java.vendor", "read";
+ permission java.util.PropertyPermission "java.vendor.url", "read";
+ permission java.util.PropertyPermission "java.class.version", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.version", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "path.separator", "read";
+ permission java.util.PropertyPermission "line.separator", "read";
+
+ permission java.util.PropertyPermission "java.specification.version", "read";
+ permission java.util.PropertyPermission "java.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.specification.name", "read";
+
+ permission java.util.PropertyPermission "java.vm.specification.version", "read";
+ permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.specification.name", "read";
+ permission java.util.PropertyPermission "java.vm.version", "read";
+ permission java.util.PropertyPermission "java.vm.vendor", "read";
+ permission java.util.PropertyPermission "java.vm.name", "read";
};
diff --git a/src/share/lib/security/java.security-linux b/src/share/lib/security/java.security-linux
index d27f71e1ab415c17f70106d9d3219927f3179349..ed8ba6060358f2609af40bc826f540153289fe9d 100644
--- a/src/share/lib/security/java.security-linux
+++ b/src/share/lib/security/java.security-linux
@@ -497,3 +497,19 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+#
+# Default ephemeral port ranges (operating system specific)
+# used by java.net.SocketPermission to interpret the meaning of the special
+# port value zero, as in the following example:
+#
+# SocketPermission("localhost:0" , "listen");
+#
+# These can be overridden by the system properties:
+#
+# jdk.net.ephemeralPortRange.low and
+# jdk.net.ephemeralPortRange.high
+#
+# respectively.
+#
+network.ephemeralPortRange.low=32768
+network.ephemeralPortRange.high=65535
diff --git a/src/share/lib/security/java.security-macosx b/src/share/lib/security/java.security-macosx
index dc4d3f64861d55ea7bb683c6abdb197d4ace418d..1f3ac7a57713bc2539e810c8fab07567ce3f6402 100644
--- a/src/share/lib/security/java.security-macosx
+++ b/src/share/lib/security/java.security-macosx
@@ -498,3 +498,21 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+
+#
+# Default ephemeral port ranges (operating system specific)
+# used by java.net.SocketPermission to interpret the meaning of the special
+# port value zero, as in the following example:
+#
+# SocketPermission("localhost:0" , "listen");
+#
+# These can be overridden by the system properties:
+#
+# jdk.net.ephemeralPortRange.low and
+# jdk.net.ephemeralPortRange.high
+#
+# respectively.
+#
+network.ephemeralPortRange.low=49152
+network.ephemeralPortRange.high=65535
+
diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris
index 3ccc0647c568da1ddcdf93ed954b7c505d8d7cf5..c4d84a487b5640f829c888b34c152c2c14a13ffa 100644
--- a/src/share/lib/security/java.security-solaris
+++ b/src/share/lib/security/java.security-solaris
@@ -497,3 +497,20 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+
+#
+# Default ephemeral port ranges (operating system specific)
+# used by java.net.SocketPermission to interpret the meaning of the special
+# port value zero, as in the following example:
+#
+# SocketPermission("localhost:0" , "listen");
+#
+# These can be overridden by the system properties:
+#
+# jdk.net.ephemeralPortRange.low and
+# jdk.net.ephemeralPortRange.high
+#
+# respectively.
+#
+network.ephemeralPortRange.low=32768
+network.ephemeralPortRange.high=65535
diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows
index ac1e93f7c1aeccfc9e8b6bd3a3118a8c8963e4bb..8b7750c9e9e11c2790917f82f5df4a7ca21e04d8 100644
--- a/src/share/lib/security/java.security-windows
+++ b/src/share/lib/security/java.security-windows
@@ -498,3 +498,19 @@ jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
# Example:
# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+#
+# Default ephemeral port ranges (operating system specific)
+# used by java.net.SocketPermission to interpret the meaning of the special
+# port value zero, as in the following example:
+#
+# SocketPermission("localhost:0" , "listen");
+#
+# These can be overridden by the system properties:
+#
+# jdk.net.ephemeralPortRange.low and
+# jdk.net.ephemeralPortRange.high
+#
+# respectively.
+#
+network.ephemeralPortRange.low=49152
+network.ephemeralPortRange.high=65535
diff --git a/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java b/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java
index 73c96cfc22b5f028ed4c71f92da4f32b92435a52..3b375686335f10ba244c84ac6921481c18af83db 100644
--- a/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java
+++ b/src/solaris/classes/sun/nio/ch/sctp/SctpChannelImpl.java
@@ -187,6 +187,10 @@ public class SctpChannelImpl extends SctpChannel
SctpNet.throwAlreadyBoundException();
InetSocketAddress isa = (local == null) ?
new InetSocketAddress(0) : Net.checkAddress(local);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkListen(isa.getPort());
+ }
Net.bind(fd, isa.getAddress(), isa.getPort());
InetSocketAddress boundIsa = Net.localAddress(fd);
port = boundIsa.getPort();