summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Jensen <pauljensen@google.com>2015-08-28 11:58:50 -0400
committerThe Android Automerger <android-build@android.com>2015-09-28 16:29:49 -0700
commit2de275c9a3b0f472f617089f1f817b09f6dad493 (patch)
tree50d5efa19e9d5377bd1e95142ad1e472b229404a
parent92451b8b8183a42e5a160281bfd052047a130102 (diff)
downloadbase-2de275c9a3b0f472f617089f1f817b09f6dad493.tar.gz
Fix NOT_RESTRICTED network capability and enforce it.
With this change: 1. NOT_RESTRICTED should be removed from NetworkRequests that bring up special restricted carrier networks (e.g. IMS, FOTA). 2. NetworkRequests without NOT_RESTRICTED require CONNECTIVITY_INTERNAL permission to register 3. Binding sockets to networks without NOT_RESTRICTED requires CONNECTIVITY_INTERNAL permission Bug:21637535 Change-Id: I5991d39facaa6b690e969fe15dcbeec52e918321 (cherry picked from commit 487ffe7d3d84bf65212158f7098e8a84b5b55e09)
-rw-r--r--core/java/android/net/ConnectivityManager.java39
-rw-r--r--core/java/android/net/NetworkCapabilities.java42
-rw-r--r--core/java/android/net/NetworkRequest.java8
-rw-r--r--core/java/android/os/INetworkManagementService.aidl11
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java16
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java37
6 files changed, 109 insertions, 44 deletions
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index eb2df0bf0dd6..57706da4089f 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -939,41 +939,6 @@ public class ConnectivityManager {
return 1;
}
- /**
- * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
- * NetworkCapabilities object if all the capabilities it provides are
- * typically provided by restricted networks.
- *
- * TODO: consider:
- * - Moving to NetworkCapabilities
- * - Renaming it to guessRestrictedCapability and make it set the
- * restricted capability bit in addition to clearing it.
- * @hide
- */
- public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
- for (int capability : nc.getCapabilities()) {
- switch (capability) {
- case NetworkCapabilities.NET_CAPABILITY_CBS:
- case NetworkCapabilities.NET_CAPABILITY_DUN:
- case NetworkCapabilities.NET_CAPABILITY_EIMS:
- case NetworkCapabilities.NET_CAPABILITY_FOTA:
- case NetworkCapabilities.NET_CAPABILITY_IA:
- case NetworkCapabilities.NET_CAPABILITY_IMS:
- case NetworkCapabilities.NET_CAPABILITY_RCS:
- case NetworkCapabilities.NET_CAPABILITY_XCAP:
- case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
- continue;
- default:
- // At least one capability usually provided by unrestricted
- // networks. Conclude that this network is unrestricted.
- return;
- }
- }
- // All the capabilities are typically provided by restricted networks.
- // Conclude that this network is restricted.
- nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- }
-
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
if (networkType == TYPE_MOBILE) {
int cap = -1;
@@ -996,14 +961,14 @@ public class ConnectivityManager {
}
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
- maybeMarkCapabilitiesRestricted(netCap);
+ netCap.maybeMarkCapabilitiesRestricted();
return netCap;
} else if (networkType == TYPE_WIFI) {
if ("p2p".equals(feature)) {
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
- maybeMarkCapabilitiesRestricted(netCap);
+ netCap.maybeMarkCapabilitiesRestricted();
return netCap;
}
}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index a7f9c5bcc0ab..76c24bade95d 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -37,6 +37,7 @@ public final class NetworkCapabilities implements Parcelable {
* @hide
*/
public NetworkCapabilities() {
+ mNetworkCapabilities = DEFAULT_CAPABILITIES;
}
public NetworkCapabilities(NetworkCapabilities nc) {
@@ -53,8 +54,7 @@ public final class NetworkCapabilities implements Parcelable {
* Represents the network's capabilities. If any are specified they will be satisfied
* by any Network that matches all of them.
*/
- private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED) |
- (1 << NET_CAPABILITY_TRUSTED) | (1 << NET_CAPABILITY_NOT_VPN);
+ private long mNetworkCapabilities;
/**
* Indicates this is a network that has the ability to reach the
@@ -166,6 +166,28 @@ public final class NetworkCapabilities implements Parcelable {
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_VALIDATED;
/**
+ * Capabilities that are set by default when the object is constructed.
+ */
+ private static final long DEFAULT_CAPABILITIES =
+ (1 << NET_CAPABILITY_NOT_RESTRICTED) |
+ (1 << NET_CAPABILITY_TRUSTED) |
+ (1 << NET_CAPABILITY_NOT_VPN);
+
+ /**
+ * Capabilities that suggest that a network is restricted.
+ * {@see #maybeMarkCapabilitiesRestricted}.
+ */
+ private static final long RESTRICTED_CAPABILITIES =
+ (1 << NET_CAPABILITY_CBS) |
+ (1 << NET_CAPABILITY_DUN) |
+ (1 << NET_CAPABILITY_EIMS) |
+ (1 << NET_CAPABILITY_FOTA) |
+ (1 << NET_CAPABILITY_IA) |
+ (1 << NET_CAPABILITY_IMS) |
+ (1 << NET_CAPABILITY_RCS) |
+ (1 << NET_CAPABILITY_XCAP);
+
+ /**
* Adds the given capability to this {@code NetworkCapability} instance.
* Multiple capabilities may be applied sequentially. Note that when searching
* for a network to satisfy a request, all capabilities requested must be satisfied.
@@ -248,6 +270,22 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
+ * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
+ * typically provided by restricted networks.
+ *
+ * TODO: consider:
+ * - Renaming it to guessRestrictedCapability and make it set the
+ * restricted capability bit in addition to clearing it.
+ * @hide
+ */
+ public void maybeMarkCapabilitiesRestricted() {
+ // If all the capabilities are typically provided by restricted networks, conclude that this
+ // network is restricted.
+ if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0)
+ removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
+ }
+
+ /**
* Representing the transport type. Apps should generally not care about transport. A
* request for a fast internet connection could be satisfied by a number of different
* transports. If any are specified here it will be satisfied a Network that matches
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 5a09b460b6a8..4c8e080b2dee 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -85,7 +85,13 @@ public class NetworkRequest implements Parcelable {
* Build {@link NetworkRequest} give the current set of capabilities.
*/
public NetworkRequest build() {
- return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
+ // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
+ // when later an unrestricted capability could be added to mNetworkCapabilities, in
+ // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
+ // maybeMarkCapabilitiesRestricted() doesn't add back.
+ final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
+ nc.maybeMarkCapabilitiesRestricted();
+ return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
ConnectivityManager.REQUEST_ID_UNSET);
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 5d5d2b384e04..a17438dc97d6 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -372,8 +372,10 @@ interface INetworkManagementService
/**
* Setup a new physical network.
+ * @param permission null if no permissions required to access this network. PERMISSION_NETWORK
+ * or PERMISSION_SYSTEM to set respective permission.
*/
- void createPhysicalNetwork(int netId);
+ void createPhysicalNetwork(int netId, String permission);
/**
* Setup a new VPN.
@@ -400,6 +402,13 @@ interface INetworkManagementService
void setDefaultNetId(int netId);
void clearDefaultNetId();
+ /**
+ * Set permission for a network.
+ * @param permission null to clear permissions. PERMISSION_NETWORK or PERMISSION_SYSTEM to set
+ * permission.
+ */
+ void setNetworkPermission(int netId, String permission);
+
void setPermission(String permission, in int[] uids);
void clearPermission(in int[] uids);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b72b29dbb1d2..eab535a9e91e 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -24,6 +24,7 @@ import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
@@ -3900,6 +3901,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void updateCapabilities(NetworkAgentInfo networkAgent,
NetworkCapabilities networkCapabilities) {
if (!Objects.equals(networkAgent.networkCapabilities, networkCapabilities)) {
+ if (networkAgent.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) !=
+ networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
+ try {
+ mNetd.setNetworkPermission(networkAgent.network.netId,
+ networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) ?
+ null : NetworkManagementService.PERMISSION_SYSTEM);
+ } catch (RemoteException e) {
+ loge("Exception in setNetworkPermission: " + e);
+ }
+ }
synchronized (networkAgent) {
networkAgent.networkCapabilities = networkCapabilities;
}
@@ -4329,7 +4340,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
(networkAgent.networkMisc == null ||
!networkAgent.networkMisc.allowBypass));
} else {
- mNetd.createPhysicalNetwork(networkAgent.network.netId);
+ mNetd.createPhysicalNetwork(networkAgent.network.netId,
+ networkAgent.networkCapabilities.hasCapability(
+ NET_CAPABILITY_NOT_RESTRICTED) ?
+ null : NetworkManagementService.PERMISSION_SYSTEM);
}
} catch (Exception e) {
loge("Error creating network " + networkAgent.network.netId + ": "
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 748018dd1568..18bf838ea4d0 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -120,6 +120,19 @@ public class NetworkManagementService extends INetworkManagementService.Stub
*/
public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
+ /**
+ * String to pass to netd to indicate that a network is only accessible
+ * to apps that have the CHANGE_NETWORK_STATE permission.
+ */
+ public static final String PERMISSION_NETWORK = "NETWORK";
+
+ /**
+ * String to pass to netd to indicate that a network is only
+ * accessible to system apps and those with the CONNECTIVITY_INTERNAL
+ * permission.
+ */
+ public static final String PERMISSION_SYSTEM = "SYSTEM";
+
class NetdResponseCode {
/* Keep in sync with system/netd/server/ResponseCode.h */
public static final int InterfaceListResult = 110;
@@ -1977,11 +1990,15 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
@Override
- public void createPhysicalNetwork(int netId) {
+ public void createPhysicalNetwork(int netId, String permission) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mConnector.execute("network", "create", netId);
+ if (permission != null) {
+ mConnector.execute("network", "create", netId, permission);
+ } else {
+ mConnector.execute("network", "create", netId);
+ }
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
}
@@ -2073,6 +2090,22 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
@Override
+ public void setNetworkPermission(int netId, String permission) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ try {
+ if (permission != null) {
+ mConnector.execute("network", "permission", "network", "set", permission, netId);
+ } else {
+ mConnector.execute("network", "permission", "network", "clear", netId);
+ }
+ } catch (NativeDaemonConnectorException e) {
+ throw e.rethrowAsParcelableException();
+ }
+ }
+
+
+ @Override
public void setPermission(String permission, int[] uids) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);