diff -r fda2b44112c7 -r e91bfaf4360d jdk/src/share/classes/java/net/SocketPermission.java --- a/jdk/src/share/classes/java/net/SocketPermission.java Thu Oct 24 10:02:26 2013 -0700 +++ b/jdk/src/share/classes/java/net/SocketPermission.java Thu Oct 24 20:39:21 2013 +0100 @@ -34,6 +34,9 @@ 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 @@ * 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 @@ * 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 @@
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 @@
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"));
@@ -360,6 +376,14 @@
}
/**
+ * 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
* called.
@@ -850,10 +874,21 @@
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 @@
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