Merge changes I30f8814c,Ifdf67318,If312b8f8 into main
* changes:
Rename hasCarrierPrivilege... to isCarrierServiceUid...
Detect discrepancies in subIds
Allow carrier service UIDs to access their own WiFi networks.
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index a8d925f..8f29078 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -5263,7 +5263,7 @@
private boolean hasCarrierPrivilegeForNetworkCaps(final int callingUid,
@NonNull final NetworkCapabilities caps) {
if (mCarrierPrivilegeAuthenticator != null) {
- return mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ return mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
callingUid, caps);
}
return false;
diff --git a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
index a39345e..5705ebe 100644
--- a/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
+++ b/service/src/com/android/server/connectivity/CarrierPrivilegeAuthenticator.java
@@ -17,6 +17,7 @@
package com.android.server.connectivity;
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static com.android.server.connectivity.ConnectivityFlags.CARRIER_SERVICE_CHANGED_USE_CALLBACK;
@@ -31,6 +32,8 @@
import android.net.NetworkCapabilities;
import android.net.NetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
+import android.net.TransportInfo;
+import android.net.wifi.WifiInfo;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
@@ -211,12 +214,13 @@
*
* This returns whether the passed UID is the carrier service package for the subscription ID
* stored in the telephony network specifier in the passed network capabilities.
- * If the capabilities don't code for a cellular network, or if they don't have the
+ * If the capabilities don't code for a cellular or Wi-Fi network, or if they don't have the
* subscription ID in their specifier, this returns false.
*
- * This method can be used to check that a network request for {@link NET_CAPABILITY_CBS} is
- * allowed for the UID of a caller, which must hold carrier privilege and provide the carrier
- * config.
+ * This method can be used to check that a network request that requires the UID to be
+ * the carrier service UID is indeed called by such a UID. An example of such a network could
+ * be a network with the {@link android.net.NetworkCapabilities#NET_CAPABILITY_CBS}
+ * capability.
* It can also be used to check that a factory is entitled to grant access to a given network
* to a given UID on grounds that it is the carrier service package.
*
@@ -224,13 +228,28 @@
* @param networkCapabilities the network capabilities for which carrier privilege is checked.
* @return true if uid provides the relevant carrier config else false.
*/
- public boolean hasCarrierPrivilegeForNetworkCapabilities(int callingUid,
+ public boolean isCarrierServiceUidForNetworkCapabilities(int callingUid,
@NonNull NetworkCapabilities networkCapabilities) {
if (callingUid == Process.INVALID_UID) return false;
- if (!networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)) {
- return false;
+ final int subId;
+ if (networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)) {
+ subId = getSubIdFromTelephonySpecifier(networkCapabilities.getNetworkSpecifier());
+ } else if (networkCapabilities.hasSingleTransportBesidesTest(TRANSPORT_WIFI)) {
+ subId = getSubIdFromWifiTransportInfo(networkCapabilities.getTransportInfo());
+ } else {
+ subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
}
- final int subId = getSubIdFromNetworkSpecifier(networkCapabilities.getNetworkSpecifier());
+ if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+ && !networkCapabilities.getSubscriptionIds().contains(subId)) {
+ // Ideally, the code above should just use networkCapabilities.getSubscriptionIds()
+ // for simplicity and future-proofing. However, this is not the historical behavior,
+ // and there is no enforcement that they do not differ, so log a terrible failure if
+ // they do not match to gain confidence this never happens.
+ // TODO : when there is confidence that this never happens, rewrite the code above
+ // with NetworkCapabilities#getSubscriptionIds.
+ Log.wtf(TAG, "NetworkCapabilities subIds are inconsistent between "
+ + "specifier/transportInfo and mSubIds : " + networkCapabilities);
+ }
if (SubscriptionManager.INVALID_SUBSCRIPTION_ID == subId) return false;
return callingUid == getCarrierServiceUidForSubId(subId);
}
@@ -259,14 +278,6 @@
}
@VisibleForTesting
- int getSubIdFromNetworkSpecifier(NetworkSpecifier specifier) {
- if (specifier instanceof TelephonyNetworkSpecifier) {
- return ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
- }
- return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
- }
-
- @VisibleForTesting
int getUidForPackage(String pkgName) {
if (pkgName == null) {
return Process.INVALID_UID;
@@ -291,8 +302,22 @@
return getUidForPackage(getCarrierServicePackageNameForLogicalSlot(slotId));
}
- // Helper methods to avoid having to deal with UnsupportedApiLevelException.
+ @VisibleForTesting
+ int getSubIdFromTelephonySpecifier(@Nullable final NetworkSpecifier specifier) {
+ if (specifier instanceof TelephonyNetworkSpecifier) {
+ return ((TelephonyNetworkSpecifier) specifier).getSubscriptionId();
+ }
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ }
+ int getSubIdFromWifiTransportInfo(@Nullable final TransportInfo info) {
+ if (info instanceof WifiInfo) {
+ return ((WifiInfo) info).getSubscriptionId();
+ }
+ return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ }
+
+ // Helper methods to avoid having to deal with UnsupportedApiLevelException.
private void addCarrierPrivilegesListener(@NonNull final Executor executor,
@NonNull final PrivilegeListener listener) {
try {
diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
index 567fd41..50cad45 100644
--- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java
@@ -23,6 +23,7 @@
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
import static android.net.NetworkCapabilities.TRANSPORT_ETHERNET;
import static android.net.NetworkCapabilities.TRANSPORT_TEST;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import static android.net.NetworkCapabilities.transportNamesOf;
import android.annotation.NonNull;
@@ -1591,12 +1592,13 @@
return false;
}
- // Factories that make cell networks can allow the UID for the carrier service package.
+ // Factories that make cell/wifi 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.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)
+ && (nc.hasSingleTransportBesidesTest(TRANSPORT_CELLULAR)
+ || nc.hasSingleTransportBesidesTest(TRANSPORT_WIFI))
&& (1 == nc.getAllowedUidsNoCopy().size())
- && (carrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ && (carrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
nc.getAllowedUidsNoCopy().valueAt(0), nc))) {
return true;
}
diff --git a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
index 3b6607f..225408c 100644
--- a/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
+++ b/tests/cts/net/src/android/net/cts/NetworkAgentTest.kt
@@ -757,8 +757,8 @@
val timeout = SystemClock.elapsedRealtime() + DEFAULT_TIMEOUT_MS
while (true) {
if (SystemClock.elapsedRealtime() > timeout) {
- fail("Couldn't make $servicePackage the service package for $defaultSubId: "
- + "dumpsys connectivity".execute().split("\n")
+ fail("Couldn't make $servicePackage the service package for $defaultSubId: " +
+ "dumpsys connectivity".execute().split("\n")
.filter { it.contains("Logical slot = $defaultSlotIndex.*") })
}
if ("dumpsys connectivity"
@@ -772,10 +772,14 @@
Thread.sleep(500)
}
- // Cell is allowed to set UIDs, but not WIFI/BLUETOOTH or agents with multiple
+ // Cell and WiFi are allowed to set UIDs, but not Bluetooth or agents with multiple
// transports.
doTestAllowedUids(defaultSubId, TRANSPORT_CELLULAR, uid, expectUidsPresent = true)
- doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = false)
+ if (SdkLevel.isAtLeastV()) {
+ // Cannot be tested before V because WifiInfo.Builder#setSubscriptionId doesn't
+ // exist
+ doTestAllowedUids(defaultSubId, TRANSPORT_WIFI, uid, expectUidsPresent = true)
+ }
doTestAllowedUids(defaultSubId, TRANSPORT_BLUETOOTH, uid, expectUidsPresent = false)
doTestAllowedUids(defaultSubId, intArrayOf(TRANSPORT_CELLULAR, TRANSPORT_WIFI), uid,
expectUidsPresent = false)
diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
index 9470a08..9fad766 100755
--- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java
@@ -79,7 +79,6 @@
import static android.net.ConnectivityManager.TYPE_ETHERNET;
import static android.net.ConnectivityManager.TYPE_MOBILE;
import static android.net.ConnectivityManager.TYPE_MOBILE_SUPL;
-import static android.net.ConnectivityManager.TYPE_NONE;
import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.TYPE_WIFI;
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
@@ -17531,7 +17530,7 @@
// In this test TEST_PACKAGE_UID will be the UID of the carrier service UID.
doReturn(true).when(mCarrierPrivilegeAuthenticator)
- .hasCarrierPrivilegeForNetworkCapabilities(eq(TEST_PACKAGE_UID), any());
+ .isCarrierServiceUidForNetworkCapabilities(eq(TEST_PACKAGE_UID), any());
// Simulate a restricted telephony network. The telephony factory is entitled to set
// the access UID to the service package on any of its restricted networks.
@@ -17596,17 +17595,18 @@
// TODO : fix the builder
ncb.setNetworkSpecifier(null);
ncb.removeTransportType(TRANSPORT_CELLULAR);
- ncb.addTransportType(TRANSPORT_WIFI);
+ ncb.addTransportType(TRANSPORT_BLUETOOTH);
// Wifi does not get to set access UID, even to the correct UID
mCm.requestNetwork(new NetworkRequest.Builder()
- .addTransportType(TRANSPORT_WIFI)
+ .addTransportType(TRANSPORT_BLUETOOTH)
.removeCapability(NET_CAPABILITY_NOT_RESTRICTED)
.build(), cb);
- mWiFiAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI, new LinkProperties(), ncb.build());
- mWiFiAgent.connect(true);
- cb.expectAvailableThenValidatedCallbacks(mWiFiAgent);
+ final TestNetworkAgentWrapper bluetoothAgent = new TestNetworkAgentWrapper(
+ TRANSPORT_BLUETOOTH, new LinkProperties(), ncb.build());
+ bluetoothAgent.connect(true);
+ cb.expectAvailableThenValidatedCallbacks(bluetoothAgent);
ncb.setAllowedUids(serviceUidSet);
- mWiFiAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
+ bluetoothAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */);
cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS);
mCm.unregisterNetworkCallback(cb);
}
diff --git a/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java b/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
index 12324d8..f07593e 100644
--- a/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
+++ b/tests/unit/java/com/android/server/connectivity/CarrierPrivilegeAuthenticatorTest.java
@@ -174,9 +174,9 @@
.addTransportType(TRANSPORT_CELLULAR)
.setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
- assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid, ncBuilder.build()));
- assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid + 1, ncBuilder.build()));
}
@@ -213,9 +213,9 @@
.addTransportType(TRANSPORT_CELLULAR)
.setNetworkSpecifier(specifier)
.build();
- assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid, nc));
- assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid + 1, nc));
}
@@ -235,9 +235,9 @@
listener.onCarrierPrivilegesChanged(Collections.emptyList(), new int[] {});
listener.onCarrierServiceChanged(null, applicationInfo.uid);
- assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid, nc));
- assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid + 1, nc));
}
@@ -248,11 +248,11 @@
final NetworkCapabilities.Builder ncBuilder = new NetworkCapabilities.Builder();
ncBuilder.addTransportType(TRANSPORT_CELLULAR);
- assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid, ncBuilder.build()));
ncBuilder.setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
- assertTrue(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertTrue(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid, ncBuilder.build()));
// The builder for NetworkCapabilities doesn't allow removing the transport as long as a
@@ -261,7 +261,7 @@
ncBuilder.removeTransportType(TRANSPORT_CELLULAR);
ncBuilder.addTransportType(TRANSPORT_WIFI);
ncBuilder.setNetworkSpecifier(new TelephonyNetworkSpecifier(0));
- assertFalse(mCarrierPrivilegeAuthenticator.hasCarrierPrivilegeForNetworkCapabilities(
+ assertFalse(mCarrierPrivilegeAuthenticator.isCarrierServiceUidForNetworkCapabilities(
mCarrierConfigPkgUid, ncBuilder.build()));
}
}