Add more powerful CTS for allowedUids
This tests that the network providers are subject to appropriate
limitations as to what they can set as allowedUids – both in the
positive (can do) case, and the negative (can't do) case.
Test: this
Change-Id: I115e2a4bc02ddcd03ecf2f35130fcb0378da22bd
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index ea6d37e..6a41bc6 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -2649,6 +2649,13 @@
}
}
+ private boolean canSeeAllowedUids(final int pid, final int uid, final int netOwnerUid) {
+ return Process.SYSTEM_UID == uid
+ || netOwnerUid == uid
+ || checkAnyPermissionOf(mContext, pid, uid,
+ android.Manifest.permission.NETWORK_FACTORY);
+ }
+
@VisibleForTesting
NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
NetworkCapabilities nc, int callerPid, int callerUid) {
@@ -2670,8 +2677,7 @@
NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK)) {
newNc.setAdministratorUids(new int[0]);
}
- if (!checkAnyPermissionOf(mContext,
- callerPid, callerUid, android.Manifest.permission.NETWORK_FACTORY)) {
+ if (!canSeeAllowedUids(callerPid, callerUid, newNc.getOwnerUid())) {
newNc.setAllowedUids(new ArraySet<>());
newNc.setSubscriptionIds(Collections.emptySet());
}
@@ -3944,6 +3950,11 @@
pw.println();
dumpBpfProgramStatus(pw);
+ if (null != mCarrierPrivilegeAuthenticator) {
+ pw.println();
+ mCarrierPrivilegeAuthenticator.dump(pw);
+ }
+
pw.println();
if (!CollectionUtils.contains(args, SHORT_ARG)) {
diff --git a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
index ab7b1a7..8edceb0 100644
--- a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
+++ b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
@@ -41,6 +41,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.IndentingPrintWriter;
import com.android.modules.utils.HandlerExecutor;
import com.android.networkstack.apishim.TelephonyManagerShimImpl;
import com.android.networkstack.apishim.common.TelephonyManagerShim;
@@ -125,11 +126,13 @@
private class PrivilegeListener implements CarrierPrivilegesListenerShim {
public final int mLogicalSlot;
+
PrivilegeListener(final int logicalSlot) {
mLogicalSlot = logicalSlot;
}
- @Override public void onCarrierPrivilegesChanged(
+ @Override
+ public void onCarrierPrivilegesChanged(
@NonNull List<String> privilegedPackageNames,
@NonNull int[] privilegedUids) {
if (mUseCallbacksForServiceChanged) return;
@@ -209,7 +212,9 @@
public boolean hasCarrierPrivilegeForNetworkCapabilities(int callingUid,
@NonNull NetworkCapabilities networkCapabilities) {
if (callingUid == Process.INVALID_UID) return false;
- if (!networkCapabilities.hasSingleTransport(TRANSPORT_CELLULAR)) return false;
+ if (!networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)) {
+ return false;
+ }
final int subId = getSubIdFromNetworkSpecifier(networkCapabilities.getNetworkSpecifier());
if (SubscriptionManager.INVALID_SUBSCRIPTION_ID == subId) return false;
return callingUid == getCarrierServiceUidForSubId(subId);
@@ -292,4 +297,16 @@
Log.e(TAG, "removeCarrierPrivilegesListener API is not available");
}
}
+
+ public void dump(IndentingPrintWriter pw) {
+ pw.println("CarrierPrivilegeAuthenticator:");
+ synchronized (mLock) {
+ final int size = mCarrierServiceUid.size();
+ for (int i = 0; i < size; ++i) {
+ final int logicalSlot = mCarrierServiceUid.keyAt(i);
+ final int serviceUid = mCarrierServiceUid.valueAt(i);
+ pw.println("Logical slot = " + logicalSlot + " : uid = " + serviceUid);
+ }
+ }
+ }
}
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index 7cd3cc8..567fd41 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
import static android.net.NetworkCapabilities.NET_CAPABILITY_LOCAL_NETWORK;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -1549,7 +1550,7 @@
* @param hasAutomotiveFeature true if this device has the automotive feature, false otherwise
* @param authenticator the carrier privilege authenticator to check for telephony constraints
*/
- public static void restrictCapabilitiesFromNetworkAgent(@NonNull final NetworkCapabilities nc,
+ public void restrictCapabilitiesFromNetworkAgent(@NonNull final NetworkCapabilities nc,
final int creatorUid, final boolean hasAutomotiveFeature,
@NonNull final ConnectivityService.Dependencies deps,
@Nullable final CarrierPrivilegeAuthenticator authenticator) {
@@ -1562,7 +1563,7 @@
}
}
- private static boolean areAllowedUidsAcceptableFromNetworkAgent(
+ private boolean areAllowedUidsAcceptableFromNetworkAgent(
@NonNull final NetworkCapabilities nc, final boolean hasAutomotiveFeature,
@NonNull final ConnectivityService.Dependencies deps,
@Nullable final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator) {
@@ -1575,19 +1576,25 @@
// On a non-restricted network, access UIDs make no sense
if (nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) return false;
- // If this network has TRANSPORT_TEST, then the caller can do whatever they want to
- // access UIDs
- if (nc.hasTransport(TRANSPORT_TEST)) return true;
+ // If this network has TRANSPORT_TEST and nothing else, then the caller can do whatever
+ // they want to access UIDs
+ if (nc.hasSingleTransport(TRANSPORT_TEST)) return true;
- // Factories that make ethernet networks can allow UIDs for automotive devices.
- if (nc.hasSingleTransport(TRANSPORT_ETHERNET) && hasAutomotiveFeature) {
- return true;
+ if (nc.hasTransport(TRANSPORT_ETHERNET)) {
+ // Factories that make ethernet networks can allow UIDs for automotive devices.
+ if (hasAutomotiveFeature) return true;
+ // It's also admissible if the ethernet network has TRANSPORT_TEST, as long as it
+ // doesn't have NET_CAPABILITY_INTERNET so it can't become the default network.
+ if (nc.hasTransport(TRANSPORT_TEST) && !nc.hasCapability(NET_CAPABILITY_INTERNET)) {
+ return true;
+ }
+ return false;
}
// Factories that make cell networks can allow the UID for the carrier service package.
// This can only work in T where there is support for CarrierPrivilegeAuthenticator
if (null != carrierPrivilegeAuthenticator
- && nc.hasSingleTransport(TRANSPORT_CELLULAR)
+ && nc.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)
&& (1 == nc.getAllowedUidsNoCopy().size())
&& (carrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
nc.getAllowedUidsNoCopy().valueAt(0), nc))) {