summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Chalard Jean <jchalard@google.com> 2020-03-09 21:25:37 +0900
committer Chalard Jean <jchalard@google.com> 2020-03-25 16:28:50 +0900
commitd134d4ff575a8926873ccb0ca08ae536c12e85d9 (patch)
treee73a6501dc0f301ec3857f3f4b979c4f57b596b7
parent6982a7dc690508f5c428b05ac2e94a86920ed5e8 (diff)
Allow MANAGE_TEST_NETWORKS to register limited agents
This puts in force some restrictions against test networks, and in exchange relaxes the restrictions around registering a network agent that provides a test network. Test networks can only ever have transport TEST, and have only a few capabilities available to them. This is useful in particular to test CTS. See aosp/1253423 for first, basic usage of this capability. Test: IpSecManagerTunnelTest Test: new CTS aosp/1253423 Bug: 139268426 Change-Id: I47600e6097e8519e50ae771daa13bb6bb7640451
-rw-r--r--core/java/android/net/NetworkCapabilities.java29
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java23
2 files changed, 50 insertions, 2 deletions
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index ae5c24ecd7ae..64e93502a3b1 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -412,6 +412,20 @@ public final class NetworkCapabilities implements Parcelable {
| (1 << NET_CAPABILITY_PARTIAL_CONNECTIVITY);
/**
+ * Capabilities that are allowed for test networks. This list must be set so that it is safe
+ * for an unprivileged user to create a network with these capabilities via shell. As such,
+ * it must never contain capabilities that are generally useful to the system, such as
+ * INTERNET, IMS, SUPL, etc.
+ */
+ private static final long TEST_NETWORKS_ALLOWED_CAPABILITIES =
+ (1 << NET_CAPABILITY_NOT_METERED)
+ | (1 << NET_CAPABILITY_NOT_RESTRICTED)
+ | (1 << NET_CAPABILITY_NOT_VPN)
+ | (1 << NET_CAPABILITY_NOT_ROAMING)
+ | (1 << NET_CAPABILITY_NOT_CONGESTED)
+ | (1 << NET_CAPABILITY_NOT_SUSPENDED);
+
+ /**
* 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.
@@ -641,6 +655,21 @@ public final class NetworkCapabilities implements Parcelable {
}
/**
+ * Test networks have strong restrictions on what capabilities they can have. Enforce these
+ * restrictions.
+ * @hide
+ */
+ public void restrictCapabilitesForTestNetwork() {
+ final long originalCapabilities = mNetworkCapabilities;
+ final NetworkSpecifier originalSpecifier = mNetworkSpecifier;
+ clearAll();
+ // Reset the transports to only contain TRANSPORT_TEST.
+ mTransportTypes = (1 << TRANSPORT_TEST);
+ mNetworkCapabilities = originalCapabilities & TEST_NETWORKS_ALLOWED_CAPABILITIES;
+ mNetworkSpecifier = originalSpecifier;
+ }
+
+ /**
* 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/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1ec4bc310546..c1aa42f507ec 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -40,6 +40,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
import static android.net.NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_TEST;
import static android.net.NetworkCapabilities.TRANSPORT_VPN;
import static android.net.NetworkPolicyManager.RULE_NONE;
import static android.net.NetworkPolicyManager.uidRulesToString;
@@ -52,6 +53,7 @@ import static com.android.internal.util.Preconditions.checkNotNull;
import static java.util.Map.Entry;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
@@ -2696,10 +2698,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
switch (msg.what) {
case NetworkAgent.EVENT_NETWORK_CAPABILITIES_CHANGED: {
- final NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
+ NetworkCapabilities networkCapabilities = (NetworkCapabilities) msg.obj;
if (networkCapabilities.hasConnectivityManagedCapability()) {
Slog.wtf(TAG, "BUG: " + nai + " has CS-managed capability.");
}
+ if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+ // Make sure the original object is not mutated. NetworkAgent normally
+ // makes a copy of the capabilities when sending the message through
+ // the Messenger, but if this ever changes, not making a defensive copy
+ // here will give attack vectors to clients using this code path.
+ networkCapabilities = new NetworkCapabilities(networkCapabilities);
+ networkCapabilities.restrictCapabilitesForTestNetwork();
+ }
updateCapabilities(nai.getCurrentScore(), nai, networkCapabilities);
break;
}
@@ -5772,7 +5782,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
public Network registerNetworkAgent(Messenger messenger, NetworkInfo networkInfo,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int currentScore, NetworkAgentConfig networkAgentConfig, int providerId) {
- enforceNetworkFactoryPermission();
+ if (networkCapabilities.hasTransport(TRANSPORT_TEST)) {
+ enforceAnyPermissionOf(Manifest.permission.MANAGE_TEST_NETWORKS);
+ // Strictly, sanitizing here is unnecessary as the capabilities will be sanitized in
+ // the call to mixInCapabilities below anyway, but sanitizing here means the NAI never
+ // sees capabilities that may be malicious, which might prevent mistakes in the future.
+ networkCapabilities = new NetworkCapabilities(networkCapabilities);
+ networkCapabilities.restrictCapabilitesForTestNetwork();
+ } else {
+ enforceNetworkFactoryPermission();
+ }
LinkProperties lp = new LinkProperties(linkProperties);
lp.ensureDirectlyConnectedRoutes();