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();