diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 02b8e622bb..1d65f21e6e 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -7825,6 +7825,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } nai.declaredCapabilities = new NetworkCapabilities(nc); NetworkAgentInfo.restrictCapabilitiesFromNetworkAgent(nc, nai.creatorUid, + mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE), mCarrierPrivilegeAuthenticator); } diff --git a/service/src/com/android/server/connectivity/NetworkAgentInfo.java b/service/src/com/android/server/connectivity/NetworkAgentInfo.java index 323888ac32..466e7b1e2b 100644 --- a/service/src/com/android/server/connectivity/NetworkAgentInfo.java +++ b/service/src/com/android/server/connectivity/NetworkAgentInfo.java @@ -19,6 +19,7 @@ package com.android.server.connectivity; import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; 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.transportNamesOf; @@ -1224,20 +1225,22 @@ public class NetworkAgentInfo implements Comparable, NetworkRa * * @param nc the capabilities to sanitize * @param creatorUid the UID of the process creating this network agent + * @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, - final int creatorUid, @NonNull final CarrierPrivilegeAuthenticator authenticator) { + final int creatorUid, final boolean hasAutomotiveFeature, + @Nullable final CarrierPrivilegeAuthenticator authenticator) { if (nc.hasTransport(TRANSPORT_TEST)) { nc.restrictCapabilitiesForTestNetwork(creatorUid); } - if (!areAllowedUidsAcceptableFromNetworkAgent(nc, authenticator)) { + if (!areAllowedUidsAcceptableFromNetworkAgent(nc, hasAutomotiveFeature, authenticator)) { nc.setAllowedUids(new ArraySet<>()); } } private static boolean areAllowedUidsAcceptableFromNetworkAgent( - @NonNull final NetworkCapabilities nc, + @NonNull final NetworkCapabilities nc, final boolean hasAutomotiveFeature, @Nullable final CarrierPrivilegeAuthenticator carrierPrivilegeAuthenticator) { // NCs without access UIDs are fine. if (!nc.hasAllowedUids()) return true; @@ -1252,6 +1255,11 @@ public class NetworkAgentInfo implements Comparable, NetworkRa // access UIDs if (nc.hasTransport(TRANSPORT_TEST)) return true; + // Factories that make ethernet networks can allow UIDs for automotive devices. + if (nc.hasTransport(TRANSPORT_ETHERNET) && hasAutomotiveFeature) { + return true; + } + // 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 @@ -1262,8 +1270,6 @@ public class NetworkAgentInfo implements Comparable, NetworkRa return true; } - // TODO : accept Railway callers - return false; } diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 52cebeccda..6294bff7cd 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -15518,6 +15518,27 @@ public class ConnectivityServiceTest { } + @Test + public void testAutomotiveEthernetAllowedUids() throws Exception { + mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); + mServiceContext.setPermission(MANAGE_TEST_NETWORKS, PERMISSION_GRANTED); + + // In this test the automotive feature will be enabled. + mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, true); + + // Simulate a restricted ethernet network. + final NetworkCapabilities.Builder agentNetCaps = new NetworkCapabilities.Builder() + .addTransportType(TRANSPORT_ETHERNET) + .addCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_SUSPENDED) + .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) + .removeCapability(NET_CAPABILITY_NOT_RESTRICTED); + + mEthernetNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_ETHERNET, + new LinkProperties(), agentNetCaps.build()); + validateAllowedUids(mEthernetNetworkAgent, TRANSPORT_ETHERNET, agentNetCaps); + } + @Test public void testCbsAllowedUids() throws Exception { mServiceContext.setPermission(NETWORK_FACTORY, PERMISSION_GRANTED); @@ -15527,6 +15548,24 @@ public class ConnectivityServiceTest { doReturn(true).when(mCarrierPrivilegeAuthenticator) .hasCarrierPrivilegeForNetworkCapabilities(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. + final NetworkCapabilities.Builder agentNetCaps = new NetworkCapabilities.Builder() + .addTransportType(TRANSPORT_CELLULAR) + .addCapability(NET_CAPABILITY_INTERNET) + .addCapability(NET_CAPABILITY_NOT_SUSPENDED) + .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) + .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) + .setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */)); + + mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, + new LinkProperties(), agentNetCaps.build()); + validateAllowedUids(mCellNetworkAgent, TRANSPORT_CELLULAR, agentNetCaps); + } + + private void validateAllowedUids(final TestNetworkAgentWrapper testAgent, + @NetworkCapabilities.Transport final int transportUnderTest, + final NetworkCapabilities.Builder ncb) throws Exception { final ArraySet serviceUidSet = new ArraySet<>(); serviceUidSet.add(TEST_PACKAGE_UID); final ArraySet nonServiceUidSet = new ArraySet<>(); @@ -15537,40 +15576,34 @@ public class ConnectivityServiceTest { final TestNetworkCallback cb = new TestNetworkCallback(); - // 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. - final NetworkCapabilities.Builder ncb = new NetworkCapabilities.Builder() - .addTransportType(TRANSPORT_CELLULAR) - .addCapability(NET_CAPABILITY_INTERNET) - .addCapability(NET_CAPABILITY_NOT_SUSPENDED) - .addCapability(NET_CAPABILITY_NOT_VCN_MANAGED) - .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) - .setNetworkSpecifier(new TelephonyNetworkSpecifier(1 /* subid */)); - + /* Test setting UIDs */ // Cell gets to set the service UID as access UID mCm.requestNetwork(new NetworkRequest.Builder() - .addTransportType(TRANSPORT_CELLULAR) + .addTransportType(transportUnderTest) .removeCapability(NET_CAPABILITY_NOT_RESTRICTED) .build(), cb); - mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, - new LinkProperties(), ncb.build()); - mCellNetworkAgent.connect(true); - cb.expectAvailableThenValidatedCallbacks(mCellNetworkAgent); + testAgent.connect(true); + cb.expectAvailableThenValidatedCallbacks(testAgent); ncb.setAllowedUids(serviceUidSet); - mCellNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); + testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); if (SdkLevel.isAtLeastT()) { - cb.expectCapabilitiesThat(mCellNetworkAgent, + cb.expectCapabilitiesThat(testAgent, caps -> caps.getAllowedUids().equals(serviceUidSet)); } else { // S must ignore access UIDs. cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); } + /* Test setting UIDs is rejected when expected */ + if (TRANSPORT_ETHERNET == transportUnderTest) { + mockHasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, false); + } + // ...but not to some other UID. Rejection sets UIDs to the empty set ncb.setAllowedUids(nonServiceUidSet); - mCellNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); + testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); if (SdkLevel.isAtLeastT()) { - cb.expectCapabilitiesThat(mCellNetworkAgent, + cb.expectCapabilitiesThat(testAgent, caps -> caps.getAllowedUids().isEmpty()); } else { // S must ignore access UIDs. @@ -15579,18 +15612,18 @@ public class ConnectivityServiceTest { // ...and also not to multiple UIDs even including the service UID ncb.setAllowedUids(serviceUidSetPlus); - mCellNetworkAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); + testAgent.setNetworkCapabilities(ncb.build(), true /* sendToCS */); cb.assertNoCallback(TEST_CALLBACK_TIMEOUT_MS); - mCellNetworkAgent.disconnect(); - cb.expectCallback(CallbackEntry.LOST, mCellNetworkAgent); + testAgent.disconnect(); + cb.expectCallback(CallbackEntry.LOST, testAgent); mCm.unregisterNetworkCallback(cb); // Must be unset before touching the transports, because remove and add transport types // check the specifier on the builder immediately, contradicting normal builder semantics // TODO : fix the builder ncb.setNetworkSpecifier(null); - ncb.removeTransportType(TRANSPORT_CELLULAR); + ncb.removeTransportType(transportUnderTest); ncb.addTransportType(TRANSPORT_WIFI); // Wifi does not get to set access UID, even to the correct UID mCm.requestNetwork(new NetworkRequest.Builder()