From 8d5c6eae80cb932c099a697dbc0666e13ec65000 Mon Sep 17 00:00:00 2001 From: Jacque Li Date: Mon, 21 Oct 2024 20:02:15 +0000 Subject: [PATCH] Check local network permissions when permission changes, or when user or packages is added or removed Bug: 388803658 Test: atest ConnectivityCoverageTests Change-Id: I7d098c4d9a7614d0bd40ae23869a2010ee3f0779 --- .../android/server/ConnectivityService.java | 10 +- .../connectivity/PermissionMonitor.java | 64 ++++- .../ConnectivityServiceIntegrationTest.kt | 7 +- .../server/ConnectivityServiceTest.java | 14 +- .../connectivity/PermissionMonitorTest.java | 237 +++++++++++++++++- .../connectivityservice/CSLocalAgentTests.kt | 2 - .../server/connectivityservice/base/CSTest.kt | 10 +- .../connectivityservice/base/CSTestHelpers.kt | 6 +- 8 files changed, 317 insertions(+), 33 deletions(-) diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 661a2f7dc8..6dbb1d81b5 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -564,6 +564,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // The Context is created for UserHandle.ALL. private final Context mUserAllContext; private final Dependencies mDeps; + private final PermissionMonitor.Dependencies mPermissionMonitorDeps; private final ConnectivityFlags mFlags; // 0 is full bad, 100 is full good private int mDefaultInetConditionPublished = 0; @@ -1808,12 +1809,13 @@ public class ConnectivityService extends IConnectivityManager.Stub public ConnectivityService(Context context) { this(context, getDnsResolver(context), new IpConnectivityLog(), INetd.Stub.asInterface((IBinder) context.getSystemService(Context.NETD_SERVICE)), - new Dependencies()); + new Dependencies(), new PermissionMonitor.Dependencies()); } @VisibleForTesting protected ConnectivityService(Context context, IDnsResolver dnsresolver, - IpConnectivityLog logger, INetd netd, Dependencies deps) { + IpConnectivityLog logger, INetd netd, Dependencies deps, + PermissionMonitor.Dependencies mPermDeps) { if (DBG) log("ConnectivityService starting up"); mDeps = Objects.requireNonNull(deps, "missing Dependencies"); @@ -1886,8 +1888,10 @@ public class ConnectivityService extends IConnectivityManager.Stub mNetd = netd; mBpfNetMaps = mDeps.getBpfNetMaps(mContext, netd); mHandlerThread = mDeps.makeHandlerThread("ConnectivityServiceThread"); + mPermissionMonitorDeps = mPermDeps; mPermissionMonitor = - new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mHandlerThread); + new PermissionMonitor(mContext, mNetd, mBpfNetMaps, mPermissionMonitorDeps, + mHandlerThread); mHandlerThread.start(); mHandler = new InternalHandler(mHandlerThread.getLooper()); mTrackerHandler = new NetworkStateTrackerHandler(mHandlerThread.getLooper()); diff --git a/service/src/com/android/server/connectivity/PermissionMonitor.java b/service/src/com/android/server/connectivity/PermissionMonitor.java index 73d077c2de..5de5f61ff1 100755 --- a/service/src/com/android/server/connectivity/PermissionMonitor.java +++ b/service/src/com/android/server/connectivity/PermissionMonitor.java @@ -19,6 +19,7 @@ package com.android.server.connectivity; import static android.Manifest.permission.CHANGE_NETWORK_STATE; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.INTERNET; +import static android.Manifest.permission.NEARBY_WIFI_DEVICES; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.UPDATE_DEVICE_STATS; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; @@ -40,6 +41,7 @@ import static com.android.net.module.util.CollectionUtils.toIntArray; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.compat.CompatChanges; +import android.content.AttributionSource; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -62,6 +64,7 @@ import android.os.ServiceSpecificException; import android.os.SystemConfigManager; import android.os.UserHandle; import android.os.UserManager; +import android.permission.PermissionManager; import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; @@ -98,6 +101,8 @@ public class PermissionMonitor { private final PackageManager mPackageManager; private final UserManager mUserManager; private final SystemConfigManager mSystemConfigManager; + private final PermissionManager mPermissionManager; + private final PermissionChangeListener mPermissionChangeListener; private final INetd mNetd; private final Dependencies mDeps; private final Context mContext; @@ -229,6 +234,12 @@ public class PermissionMonitor { context.getContentResolver().registerContentObserver( uri, notifyForDescendants, observer); } + + public boolean shouldEnforceLocalNetRestrictions(int uid) { + // TODO(b/394567896): Update compat change checks for enforcement + return BpfNetMaps.isAtLeast25Q2() && + CompatChanges.isChangeEnabled(RESTRICT_LOCAL_NETWORK, uid); + } } private static class MultiSet { @@ -269,13 +280,15 @@ public class PermissionMonitor { } @VisibleForTesting - PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd, + public PermissionMonitor(@NonNull final Context context, @NonNull final INetd netd, @NonNull final BpfNetMaps bpfNetMaps, @NonNull final Dependencies deps, @NonNull final HandlerThread thread) { mPackageManager = context.getPackageManager(); mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE); mSystemConfigManager = context.getSystemService(SystemConfigManager.class); + mPermissionManager = context.getSystemService(PermissionManager.class); + mPermissionChangeListener = new PermissionChangeListener(); mNetd = netd; mDeps = deps; mContext = context; @@ -286,7 +299,29 @@ public class PermissionMonitor { // This listener should finish registration by the time the system has completed // boot setup such that any changes to runtime permissions for local network // restrictions can only occur after this registration has completed. - mPackageManager.addOnPermissionsChangeListener(new PermissionChangeListener()); + mPackageManager.addOnPermissionsChangeListener(mPermissionChangeListener); + } + } + + @VisibleForTesting + void setLocalNetworkPermissions(final int uid, @Nullable final String packageName) { + if (!mDeps.shouldEnforceLocalNetRestrictions(uid)) return; + + final AttributionSource attributionSource = + new AttributionSource.Builder(uid).setPackageName(packageName).build(); + final int permissionState = mPermissionManager.checkPermissionForPreflight( + NEARBY_WIFI_DEVICES, attributionSource); + if (permissionState == PermissionManager.PERMISSION_GRANTED) { + mBpfNetMaps.removeUidFromLocalNetBlockMap(attributionSource.getUid()); + } else { + mBpfNetMaps.addUidToLocalNetBlockMap(attributionSource.getUid()); + } + if (hasSdkSandbox(uid)){ + // SDKs in the SDK RT cannot hold runtime permissions + final int sdkSandboxUid = sProcessShim.toSdkSandboxUid(uid); + if (!mBpfNetMaps.isUidBlockedFromUsingLocalNetwork(sdkSandboxUid)) { + mBpfNetMaps.addUidToLocalNetBlockMap(sdkSandboxUid); + } } } @@ -350,6 +385,7 @@ public class PermissionMonitor { uidsPerm.put(sdkSandboxUid, permission); } } + setLocalNetworkPermissions(uid, app.packageName); } return uidsPerm; } @@ -597,7 +633,7 @@ public class PermissionMonitor { final List apps = getInstalledPackagesAsUser(user); - // Save all apps + // Save all apps in mAllApps updateAllApps(apps); // Uids network permissions @@ -634,6 +670,11 @@ public class PermissionMonitor { final int uid = allUids.keyAt(i); if (user.equals(UserHandle.getUserHandleForUid(uid))) { mUidToNetworkPerm.delete(uid); + if (mDeps.shouldEnforceLocalNetRestrictions(uid)) { + mBpfNetMaps.removeUidFromLocalNetBlockMap(uid); + if (hasSdkSandbox(uid)) mBpfNetMaps.removeUidFromLocalNetBlockMap( + sProcessShim.toSdkSandboxUid(uid)); + } removedUids.put(uid, allUids.valueAt(i)); } } @@ -828,6 +869,7 @@ public class PermissionMonitor { } sendUidsNetworkPermission(apps, true /* add */); } + setLocalNetworkPermissions(uid, packageName); // If the newly-installed package falls within some VPN's uid range, update Netd with it. // This needs to happen after the mUidToNetworkPerm update above, since @@ -872,6 +914,11 @@ public class PermissionMonitor { synchronized void onPackageRemoved(@NonNull final String packageName, final int uid) { // Update uid permission. updateAppIdTrafficPermission(uid); + if (BpfNetMaps.isAtLeast25Q2()) { + mBpfNetMaps.removeUidFromLocalNetBlockMap(uid); + if (hasSdkSandbox(uid)) mBpfNetMaps.removeUidFromLocalNetBlockMap( + sProcessShim.toSdkSandboxUid(uid)); + } // Get the appId permission from all users then send the latest permission to netd. final int appId = UserHandle.getAppId(uid); final int appIdTrafficPerm = getAppIdTrafficPermission(appId); @@ -1324,16 +1371,7 @@ public class PermissionMonitor { private class PermissionChangeListener implements PackageManager.OnPermissionsChangedListener { @Override public void onPermissionsChanged(int uid) { - // RESTRICT_LOCAL_NETWORK is a compat change that is enabled when developers manually - // opt-in to this change, or when the app's targetSdkVersion is greater than 36. - // The RESTRICT_LOCAL_NETWORK compat change is used here instead of the - // Flags.restrictLocalNetwork() is used to offer the feature to devices, but it will - // only be enforced when develoeprs choose to enable it. - // TODO(b/394567896): Update compat change checks - if (CompatChanges.isChangeEnabled(RESTRICT_LOCAL_NETWORK, uid) - && BpfNetMaps.isAtLeast25Q2()) { - // TODO(b/388803658): Update network permissions and record change - } + setLocalNetworkPermissions(uid, null); } } } diff --git a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt index cc9445da88..437eb819ab 100644 --- a/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt +++ b/tests/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt @@ -62,6 +62,7 @@ import com.android.server.connectivity.CarrierPrivilegeAuthenticator import com.android.server.connectivity.ConnectivityResources import com.android.server.connectivity.MockableSystemProperties import com.android.server.connectivity.MultinetworkPolicyTracker +import com.android.server.connectivity.PermissionMonitor import com.android.server.connectivity.ProxyTracker import com.android.server.connectivity.SatelliteAccessController import com.android.testutils.DevSdkIgnoreRunner @@ -222,7 +223,7 @@ class ConnectivityServiceIntegrationTest { } private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService( - context, dnsResolver, log, netd, deps) + context, dnsResolver, log, netd, deps, PermissionMonitorDependencies()) private inner class TestDependencies : ConnectivityService.Dependencies() { override fun getNetworkStack() = networkStackClient @@ -277,6 +278,10 @@ class ConnectivityServiceIntegrationTest { override fun makeL2capNetworkProvider(context: Context) = null } + private inner class PermissionMonitorDependencies : PermissionMonitor.Dependencies() { + override fun shouldEnforceLocalNetRestrictions(uid: Int) = false + } + @After fun tearDown() { nsInstrumentation.clearAllState() diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index 1562dad55f..b7aa387e91 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -154,6 +154,7 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIAL import static android.net.Proxy.PROXY_CHANGE_ACTION; import static android.net.RouteInfo.RTN_UNREACHABLE; import static android.net.connectivity.ConnectivityCompatChanges.NETWORK_BLOCKED_WITHOUT_INTERNET_PERMISSION; +import static android.net.connectivity.ConnectivityCompatChanges.RESTRICT_LOCAL_NETWORK; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED; import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE; @@ -257,6 +258,7 @@ import android.app.BroadcastOptions; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.admin.DevicePolicyManager; +import android.app.compat.CompatChanges; import android.app.usage.NetworkStatsManager; import android.compat.testing.PlatformCompatChangeRule; import android.content.BroadcastReceiver; @@ -426,6 +428,7 @@ import com.android.server.connectivity.Nat464Xlat; import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkNotificationManager; import com.android.server.connectivity.NetworkNotificationManager.NotificationType; +import com.android.server.connectivity.PermissionMonitor; import com.android.server.connectivity.ProxyTracker; import com.android.server.connectivity.QosCallbackTracker; import com.android.server.connectivity.SatelliteAccessController; @@ -594,6 +597,7 @@ public class ConnectivityServiceTest { private MockContext mServiceContext; private HandlerThread mCsHandlerThread; private ConnectivityServiceDependencies mDeps; + private PermissionMonitorDependencies mPermDeps; private AutomaticOnOffKeepaliveTrackerDependencies mAutoOnOffKeepaliveDependencies; private ConnectivityService mService; private WrappedConnectivityManager mCm; @@ -1921,6 +1925,7 @@ public class ConnectivityServiceTest { doReturn(mResources).when(mockResContext).getResources(); ConnectivityResources.setResourcesContextForTest(mockResContext); mDeps = new ConnectivityServiceDependencies(mockResContext); + mPermDeps = new PermissionMonitorDependencies(); doReturn(true).when(mMockKeepaliveTrackerDependencies) .isAddressTranslationEnabled(mServiceContext); doReturn(new ConnectivityResources(mockResContext)).when(mMockKeepaliveTrackerDependencies) @@ -1933,7 +1938,7 @@ public class ConnectivityServiceTest { mMockDnsResolver, mock(IpConnectivityLog.class), mMockNetd, - mDeps); + mDeps, mPermDeps); mService.mLingerDelayMs = TEST_LINGER_DELAY_MS; mService.mNascentDelayMs = TEST_NASCENT_DELAY_MS; @@ -2389,6 +2394,13 @@ public class ConnectivityServiceTest { } } + static class PermissionMonitorDependencies extends PermissionMonitor.Dependencies { + @Override + public boolean shouldEnforceLocalNetRestrictions(int uid) { + return false; + } + } + private class AutomaticOnOffKeepaliveTrackerDependencies extends AutomaticOnOffKeepaliveTracker.Dependencies { AutomaticOnOffKeepaliveTrackerDependencies(Context context) { diff --git a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java index 55c68b7bd6..ec9c6b0e48 100644 --- a/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java +++ b/tests/unit/java/com/android/server/connectivity/PermissionMonitorTest.java @@ -21,6 +21,7 @@ import static android.Manifest.permission.CHANGE_WIFI_STATE; import static android.Manifest.permission.CONNECTIVITY_INTERNAL; import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS; import static android.Manifest.permission.INTERNET; +import static android.Manifest.permission.NEARBY_WIFI_DEVICES; import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS; import static android.Manifest.permission.UPDATE_DEVICE_STATS; @@ -31,6 +32,7 @@ import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED; import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED; import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.MATCH_ANY_USER; +import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.net.ConnectivitySettingsManager.UIDS_ALLOWED_ON_RESTRICTED_NETWORKS; import static android.net.INetd.PERMISSION_INTERNET; import static android.net.INetd.PERMISSION_NETWORK; @@ -39,16 +41,20 @@ import static android.net.INetd.PERMISSION_SYSTEM; import static android.net.INetd.PERMISSION_UNINSTALLED; import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS; import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK; +import static android.net.connectivity.ConnectivityCompatChanges.RESTRICT_LOCAL_NETWORK; import static android.os.Process.SYSTEM_UID; +import static android.permission.PermissionManager.PERMISSION_GRANTED; import static com.android.server.connectivity.PermissionMonitor.isHigherNetworkPermission; import static com.android.testutils.TestPermissionUtil.runAsShell; +import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; import static junit.framework.Assert.fail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assume.assumeTrue; import static org.mockito.AdditionalMatchers.aryEq; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -68,6 +74,8 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.compat.testing.PlatformCompatChangeRule; +import android.content.AttributionSource; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -85,7 +93,9 @@ import android.os.Process; import android.os.SystemConfigManager; import android.os.UserHandle; import android.os.UserManager; +import android.permission.PermissionManager; import android.provider.Settings; +import android.util.ArraySet; import android.util.SparseIntArray; import androidx.annotation.NonNull; @@ -102,9 +112,13 @@ import com.android.testutils.DevSdkIgnoreRule; import com.android.testutils.DevSdkIgnoreRunner; import com.android.testutils.HandlerUtils; +import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; + import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import org.mockito.AdditionalAnswers; import org.mockito.ArgumentCaptor; @@ -121,6 +135,8 @@ import java.util.Set; @SmallTest @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) public class PermissionMonitorTest { + @Rule + public TestRule compatChangeRule = new PlatformCompatChangeRule(); private static final int MOCK_USER_ID1 = 0; private static final int MOCK_USER_ID2 = 1; private static final int MOCK_USER_ID3 = 2; @@ -162,9 +178,14 @@ public class PermissionMonitorTest { private static final int PERMISSION_TRAFFIC_ALL = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS; private static final int TIMEOUT_MS = 2_000; + // The ACCESS_LOCAL_NETWORK permission is not available yet. For the time being, use + // NEARBY_WIFI_DEVICES as a means to develop, for expediency. + // TODO(b/375236298): remove this constant when the ACCESS_LOCAL_NETWORK permission is defined. + private static final String ACCESS_LOCAL_NETWORK = NEARBY_WIFI_DEVICES; @Mock private Context mContext; @Mock private PackageManager mPackageManager; + @Mock private PermissionManager mPermissionManager; @Mock private INetd mNetdService; @Mock private UserManager mUserManager; @Mock private PermissionMonitor.Dependencies mDeps; @@ -183,6 +204,7 @@ public class PermissionMonitorTest { when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager); doReturn(List.of(MOCK_USER1)).when(mUserManager).getUserHandles(eq(true)); + when(mContext.getSystemService(PermissionManager.class)).thenReturn(mPermissionManager); when(mContext.getSystemServiceName(SystemConfigManager.class)) .thenReturn(Context.SYSTEM_CONFIG_SERVICE); when(mContext.getSystemService(Context.SYSTEM_CONFIG_SERVICE)) @@ -295,19 +317,28 @@ public class PermissionMonitorTest { return result; } - private void buildAndMockPackageInfoWithPermissions(String packageName, int uid, + private PackageInfo buildAndMockPackageInfoWithPermissions(String packageName, int uid, String... permissions) throws Exception { final PackageInfo packageInfo = buildPackageInfo(packageName, uid, permissions); // This will return the wrong UID for the package when queried with other users. doReturn(packageInfo).when(mPackageManager) .getPackageInfo(eq(packageName), anyInt() /* flag */); + if (BpfNetMaps.isAtLeast25Q2()) { + // Runtime permission checks for local net restrictions were introduced in 25Q2 + for (String permission : permissions) { + doReturn(PERMISSION_GRANTED).when(mPermissionManager).checkPermissionForPreflight( + eq(permission), + argThat(attributionSource -> attributionSource.getUid() == uid)); + } + } final String[] oldPackages = mPackageManager.getPackagesForUid(uid); // If it's duplicated package, no need to set it again. - if (CollectionUtils.contains(oldPackages, packageName)) return; + if (CollectionUtils.contains(oldPackages, packageName)) return packageInfo; // Combine the package if this uid is shared with other packages. final String[] newPackages = appendElement(String.class, oldPackages, packageName); doReturn(newPackages).when(mPackageManager).getPackagesForUid(eq(uid)); + return packageInfo; } private void startMonitoring() { @@ -342,7 +373,7 @@ public class PermissionMonitorTest { private void addPackage(String packageName, int uid, String... permissions) throws Exception { buildAndMockPackageInfoWithPermissions(packageName, uid, permissions); - processOnHandlerThread(() -> mPermissionMonitor.onPackageAdded(packageName, uid)); + onPackageAdded(packageName, uid); } private void removePackage(String packageName, int uid) { @@ -354,7 +385,12 @@ public class PermissionMonitorTest { final String[] newPackages = Arrays.stream(oldPackages).filter(e -> !e.equals(packageName)) .toArray(String[]::new); doReturn(newPackages).when(mPackageManager).getPackagesForUid(eq(uid)); - processOnHandlerThread(() -> mPermissionMonitor.onPackageRemoved(packageName, uid)); + if (BpfNetMaps.isAtLeast25Q2()){ + // Runtime permission checks for local net restrictions were introduced in 25Q2 + doReturn(PERMISSION_DENIED).when(mPermissionManager).checkPermissionForPreflight( + anyString(), argThat(as -> as.getUid() == uid)); + } + onPackageRemoved(packageName, uid); } @Test @@ -585,6 +621,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testHasUseBackgroundNetworksPermission() throws Exception { assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID)); assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID); @@ -606,6 +643,7 @@ public class PermissionMonitorTest { private class BpfMapMonitor { private final SparseIntArray mAppIdsTrafficPermission = new SparseIntArray(); + private final ArraySet mLocalNetBlockedUids = new ArraySet<>(); private static final int DOES_NOT_EXIST = -2; BpfMapMonitor(BpfNetMaps mockBpfmap) throws Exception { @@ -618,6 +656,18 @@ public class PermissionMonitorTest { } return null; }).when(mockBpfmap).setNetPermForUids(anyInt(), any(int[].class)); + doAnswer((InvocationOnMock invocation) -> { + final Object[] args = invocation.getArguments(); + final int uid = (int) args[0]; + mLocalNetBlockedUids.add(uid); + return null; + }).when(mockBpfmap).addUidToLocalNetBlockMap(anyInt()); + doAnswer((InvocationOnMock invocation) -> { + final Object[] args = invocation.getArguments(); + final int uid = (int) args[0]; + mLocalNetBlockedUids.remove(uid); + return null; + }).when(mockBpfmap).removeUidFromLocalNetBlockMap(anyInt()); } public void expectTrafficPerm(int permission, Integer... appIds) { @@ -642,6 +692,18 @@ public class PermissionMonitorTest { } } } + + public boolean hasLocalNetPermissions(int uid) { + return !mLocalNetBlockedUids.contains(uid); + } + + public boolean isUidPresentInLocalNetBlockMap(int uid) { + return mLocalNetBlockedUids.contains(uid); + } + + public boolean hasBlockedLocalNetForSandboxUid(int sandboxUid) { + return mLocalNetBlockedUids.contains(sandboxUid); + } } private class NetdMonitor { @@ -725,6 +787,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUserAndPackageAddRemove() throws Exception { // MOCK_UID11: MOCK_PACKAGE1 only has network permission. // SYSTEM_APP_UID11: SYSTEM_PACKAGE1 has system permission. @@ -814,6 +877,48 @@ public class PermissionMonitorTest { MOCK_APPID1); } + @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) + public void testLocalNetRestrictions_onUserAdded() throws Exception { + assumeTrue(BpfNetMaps.isAtLeast25Q2()); + doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt()); + when(mPermissionManager.checkPermissionForPreflight( + anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED); + final PackageInfo packageInfo = buildAndMockPackageInfoWithPermissions( + MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE); + // Set package for all users on devices + doReturn(List.of(packageInfo)).when(mPackageManager) + .getInstalledPackagesAsUser(anyInt(), eq(MOCK_USER1.getIdentifier())); + onUserAdded(MOCK_USER1); + + assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + if (hasSdkSandbox(MOCK_UID11)) { + assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid( + mProcessShim.toSdkSandboxUid(MOCK_UID11))); + } + } + + @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) + public void testLocalNetRestrictions_onUserRemoved() throws Exception { + assumeTrue(BpfNetMaps.isAtLeast25Q2()); + doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt()); + when(mPermissionManager.checkPermissionForPreflight( + anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED); + final PackageInfo packageInfo = buildAndMockPackageInfoWithPermissions( + MOCK_PACKAGE1, MOCK_UID11, CHANGE_NETWORK_STATE); + // Set package for all users on devices + doReturn(List.of(packageInfo)).when(mPackageManager) + .getInstalledPackagesAsUser(anyInt(), eq(MOCK_USER1.getIdentifier())); + onUserAdded(MOCK_USER1); + assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + + onUserRemoved(MOCK_USER1); + assertFalse(mBpfMapMonitor.isUidPresentInLocalNetBlockMap(MOCK_UID11)); + } + private void doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates(@Nullable String ifName) throws Exception { doReturn(List.of( @@ -860,11 +965,13 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception { doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates("tun0"); } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdatesWithWildcard() throws Exception { doTestUidFilteringDuringVpnConnectDisconnectAndUidUpdates(null /* ifName */); @@ -897,16 +1004,19 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception { doTestUidFilteringDuringPackageInstallAndUninstall("tun0"); } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidFilteringDuringPackageInstallAndUninstallWithWildcard() throws Exception { doTestUidFilteringDuringPackageInstallAndUninstall(null /* ifName */); } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testLockdownUidFilteringWithLockdownEnableDisable() { doReturn(List.of( buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, @@ -938,6 +1048,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testLockdownUidFilteringWithLockdownEnableDisableWithMultiAdd() { doReturn(List.of( buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, @@ -979,6 +1090,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testLockdownUidFilteringWithLockdownEnableDisableWithMultiAddAndOverlap() { doReturn(List.of(buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, CONNECTIVITY_USE_RESTRICTED_NETWORKS), @@ -1039,6 +1151,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testLockdownUidFilteringWithLockdownEnableDisableWithDuplicates() { doReturn(List.of( buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, @@ -1073,6 +1186,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testLockdownUidFilteringWithInstallAndUnInstall() { doReturn(List.of( buildPackageInfo(SYSTEM_PACKAGE1, SYSTEM_APP_UID11, CHANGE_NETWORK_STATE, @@ -1109,15 +1223,13 @@ public class PermissionMonitorTest { // called multiple times with the uid corresponding to each user. private void addPackageForUsers(UserHandle[] users, String packageName, int appId) { for (final UserHandle user : users) { - processOnHandlerThread(() -> - mPermissionMonitor.onPackageAdded(packageName, user.getUid(appId))); + onPackageAdded(packageName, user.getUid(appId)); } } private void removePackageForUsers(UserHandle[] users, String packageName, int appId) { for (final UserHandle user : users) { - processOnHandlerThread(() -> - mPermissionMonitor.onPackageRemoved(packageName, user.getUid(appId))); + onPackageRemoved(packageName, user.getUid(appId)); } } @@ -1165,6 +1277,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testPackageInstall() throws Exception { addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); @@ -1173,7 +1286,25 @@ public class PermissionMonitorTest { mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID2); } + @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) + public void testLocalNetRestrictions_onPackageInstall() throws Exception { + assumeTrue(BpfNetMaps.isAtLeast25Q2()); + doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt()); + when(mPermissionManager.checkPermissionForPreflight( + anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET); + assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + + addPackage(MOCK_PACKAGE2, MOCK_UID12, ACCESS_LOCAL_NETWORK); + assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID12)); + if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid( + mProcessShim.toSdkSandboxUid(MOCK_UID12))); + } + + @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testPackageInstallSharedUid() throws Exception { addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); @@ -1185,6 +1316,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testPackageUninstallBasic() throws Exception { addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); @@ -1194,7 +1326,24 @@ public class PermissionMonitorTest { mBpfMapMonitor.expectTrafficPerm(PERMISSION_UNINSTALLED, MOCK_APPID1); } + @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) + public void testLocalNetRestrictions_onPackageUninstall() throws Exception { + assumeTrue(BpfNetMaps.isAtLeast25Q2()); + doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt()); + when(mPermissionManager.checkPermissionForPreflight( + anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED); + addPackage(MOCK_PACKAGE1, MOCK_UID11, ACCESS_LOCAL_NETWORK); + assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + + when(mPackageManager.getPackagesForUid(MOCK_UID11)).thenReturn(new String[]{}); + onPackageRemoved(MOCK_PACKAGE1, MOCK_UID11); + assertFalse(mBpfMapMonitor.isUidPresentInLocalNetBlockMap(MOCK_UID11)); + } + + @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testPackageRemoveThenAdd() throws Exception { addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); @@ -1207,7 +1356,30 @@ public class PermissionMonitorTest { mBpfMapMonitor.expectTrafficPerm(PERMISSION_INTERNET, MOCK_APPID1); } + @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) + public void testLocalNetRestrictions_onPackageRemoveThenAdd() throws Exception { + assumeTrue(BpfNetMaps.isAtLeast25Q2()); + doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt()); + when(mPermissionManager.checkPermissionForPreflight( + anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED); + addPackage(MOCK_PACKAGE1, MOCK_UID11, ACCESS_LOCAL_NETWORK); + assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid( + mProcessShim.toSdkSandboxUid(MOCK_UID11))); + + removePackage(MOCK_PACKAGE1, MOCK_UID11); + assertFalse(mBpfMapMonitor.isUidPresentInLocalNetBlockMap(MOCK_UID11)); + + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET); + assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid( + mProcessShim.toSdkSandboxUid(MOCK_UID11))); + } + + @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testPackageUpdate() throws Exception { addPackage(MOCK_PACKAGE1, MOCK_UID11); mBpfMapMonitor.expectTrafficPerm(PERMISSION_NONE, MOCK_APPID1); @@ -1217,6 +1389,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testPackageUninstallWithMultiplePackages() throws Exception { addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET, UPDATE_DEVICE_STATS); mBpfMapMonitor.expectTrafficPerm(PERMISSION_TRAFFIC_ALL, MOCK_APPID1); @@ -1248,6 +1421,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUpdateUidPermissionsFromSystemConfig() throws Exception { when(mSystemConfigManager.getSystemPermissionUids(eq(INTERNET))) .thenReturn(new int[]{ MOCK_UID11, MOCK_UID12 }); @@ -1287,6 +1461,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testIntentReceiver() throws Exception { startMonitoring(); final BroadcastReceiver receiver = expectBroadcastReceiver( @@ -1325,6 +1500,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidsAllowedOnRestrictedNetworksChanged() throws Exception { startMonitoring(); final ContentObserver contentObserver = expectRegisterContentObserver( @@ -1357,6 +1533,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidsAllowedOnRestrictedNetworksChangedWithSharedUid() throws Exception { startMonitoring(); final ContentObserver contentObserver = expectRegisterContentObserver( @@ -1390,6 +1567,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testUidsAllowedOnRestrictedNetworksChangedWithMultipleUsers() throws Exception { startMonitoring(); final ContentObserver contentObserver = expectRegisterContentObserver( @@ -1444,6 +1622,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testOnExternalApplicationsAvailable() throws Exception { // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external // and have different uids. There has no permission for both uids. @@ -1475,6 +1654,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testOnExternalApplicationsAvailable_AppsNotRegisteredOnStartMonitoring() throws Exception { startMonitoring(); @@ -1502,6 +1682,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testOnExternalApplicationsAvailableWithSharedUid() throws Exception { // Initial the permission state. MOCK_PACKAGE1 and MOCK_PACKAGE2 are installed on external @@ -1528,6 +1709,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testOnExternalApplicationsAvailableWithSharedUid_DifferentStorage() throws Exception { // Initial the permission state. MOCK_PACKAGE1 is installed on external storage and @@ -1570,6 +1752,38 @@ public class PermissionMonitorTest { assertFalse(isHigherNetworkPermission(PERMISSION_SYSTEM, PERMISSION_SYSTEM)); } + @IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM) + @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) + public void testLocalNetRestrictions_setPermChanges() throws Exception { + assumeTrue(BpfNetMaps.isAtLeast25Q2()); + doReturn(true).when(mDeps).shouldEnforceLocalNetRestrictions(anyInt()); + when(mPermissionManager.checkPermissionForPreflight( + anyString(), any(AttributionSource.class))).thenReturn(PERMISSION_DENIED); + addPackage(MOCK_PACKAGE1, MOCK_UID11, INTERNET); + assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + + // Mock permission grant + when(mPermissionManager.checkPermissionForPreflight( + eq(ACCESS_LOCAL_NETWORK), + argThat(attributionSource -> attributionSource.getUid() == MOCK_UID11))) + .thenReturn(PERMISSION_GRANTED); + mPermissionMonitor.setLocalNetworkPermissions(MOCK_UID11, null); + assertTrue(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid( + mProcessShim.toSdkSandboxUid(MOCK_UID11))); + + // Mock permission denied + when(mPermissionManager.checkPermissionForPreflight( + eq(ACCESS_LOCAL_NETWORK), + argThat(attributionSource -> attributionSource.getUid() == MOCK_UID11))) + .thenReturn(PERMISSION_DENIED); + mPermissionMonitor.setLocalNetworkPermissions(MOCK_UID11, null); + assertFalse(mBpfMapMonitor.hasLocalNetPermissions(MOCK_UID11)); + if (hasSdkSandbox(MOCK_UID12)) assertTrue(mBpfMapMonitor.hasBlockedLocalNetForSandboxUid( + mProcessShim.toSdkSandboxUid(MOCK_UID11))); + } + private void prepareMultiUserPackages() { // MOCK_USER1 has installed 3 packages // mockApp1 has no permission and share MOCK_APPID1. @@ -1602,7 +1816,7 @@ public class PermissionMonitorTest { private void addUserAndVerifyAppIdsPermissions(UserHandle user, int appId1Perm, int appId2Perm, int appId3Perm) { - processOnHandlerThread(() -> mPermissionMonitor.onUserAdded(user)); + onUserAdded(user); mBpfMapMonitor.expectTrafficPerm(appId1Perm, MOCK_APPID1); mBpfMapMonitor.expectTrafficPerm(appId2Perm, MOCK_APPID2); mBpfMapMonitor.expectTrafficPerm(appId3Perm, MOCK_APPID3); @@ -1610,13 +1824,14 @@ public class PermissionMonitorTest { private void removeUserAndVerifyAppIdsPermissions(UserHandle user, int appId1Perm, int appId2Perm, int appId3Perm) { - processOnHandlerThread(() -> mPermissionMonitor.onUserRemoved(user)); + onUserRemoved(user); mBpfMapMonitor.expectTrafficPerm(appId1Perm, MOCK_APPID1); mBpfMapMonitor.expectTrafficPerm(appId2Perm, MOCK_APPID2); mBpfMapMonitor.expectTrafficPerm(appId3Perm, MOCK_APPID3); } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testAppIdsTrafficPermission_UserAddedRemoved() { prepareMultiUserPackages(); @@ -1650,6 +1865,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testAppIdsTrafficPermission_Multiuser_PackageAdded() throws Exception { // Add two users with empty package list. onUserAdded(MOCK_USER1); @@ -1720,6 +1936,7 @@ public class PermissionMonitorTest { } @Test + @EnableCompatChanges(RESTRICT_LOCAL_NETWORK) public void testAppIdsTrafficPermission_Multiuser_PackageRemoved() throws Exception { // Add two users with empty package list. onUserAdded(MOCK_USER1); diff --git a/tests/unit/java/com/android/server/connectivityservice/CSLocalAgentTests.kt b/tests/unit/java/com/android/server/connectivityservice/CSLocalAgentTests.kt index 83fff87271..3583f849a2 100644 --- a/tests/unit/java/com/android/server/connectivityservice/CSLocalAgentTests.kt +++ b/tests/unit/java/com/android/server/connectivityservice/CSLocalAgentTests.kt @@ -54,9 +54,7 @@ import org.mockito.Mockito.eq import org.mockito.Mockito.inOrder import org.mockito.Mockito.never import org.mockito.Mockito.timeout -import org.mockito.Mockito.times import org.mockito.Mockito.verify -import org.mockito.Mockito.verifyNoMoreInteractions private const val TIMEOUT_MS = 200L private const val MEDIUM_TIMEOUT_MS = 1_000L diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt index 350a140e59..557bfd6612 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTest.kt @@ -72,6 +72,7 @@ import com.android.server.connectivity.MulticastRoutingCoordinatorService import com.android.server.connectivity.MultinetworkPolicyTracker import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies import com.android.server.connectivity.NetworkRequestStateStatsMetrics +import com.android.server.connectivity.PermissionMonitor import com.android.server.connectivity.ProxyTracker import com.android.server.connectivity.SatelliteAccessController import com.android.testutils.visibleOnHandlerThread @@ -217,6 +218,7 @@ open class CSTest { val destroySocketsWrapper = mock() val deps = CSDeps() + val permDeps = PermDeps() // Initializations that start threads are done from setUp to avoid thread leak lateinit var alarmHandlerThread: HandlerThread @@ -253,7 +255,9 @@ open class CSTest { alarmHandlerThread = HandlerThread("TestAlarmManager").also { it.start() } alarmManager = makeMockAlarmManager(alarmHandlerThread) - service = makeConnectivityService(context, netd, deps).also { it.systemReadyInternal() } + service = makeConnectivityService(context, netd, deps, permDeps).also { + it.systemReadyInternal() + } cm = ConnectivityManager(context, service) // csHandler initialization must be after makeConnectivityService since ConnectivityService // constructor starts csHandlerThread @@ -399,6 +403,10 @@ open class CSTest { override fun makeL2capNetworkProvider(context: Context) = null } + inner class PermDeps : PermissionMonitor.Dependencies() { + override fun shouldEnforceLocalNetRestrictions(uid: Int) = false + } + inner class CSContext(base: Context) : BroadcastInterceptingContext(base) { val pacProxyManager = mock() val networkPolicyManager = mock() diff --git a/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt b/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt index 6b560def55..a53d4301f6 100644 --- a/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt +++ b/tests/unit/java/com/android/server/connectivityservice/base/CSTestHelpers.kt @@ -54,6 +54,7 @@ import com.android.internal.util.test.FakeSettingsProvider import com.android.modules.utils.build.SdkLevel import com.android.server.ConnectivityService.Dependencies import com.android.server.connectivity.ConnectivityResources +import com.android.server.connectivity.PermissionMonitor import kotlin.test.fail import org.mockito.ArgumentMatchers import org.mockito.ArgumentMatchers.any @@ -192,13 +193,14 @@ internal fun initMockedResources(res: Resources) { private val TEST_LINGER_DELAY_MS = 400 private val TEST_NASCENT_DELAY_MS = 300 -internal fun makeConnectivityService(context: Context, netd: INetd, deps: Dependencies) = +internal fun makeConnectivityService(context: Context, netd: INetd, deps: Dependencies, + mPermDeps: PermissionMonitor.Dependencies) = ConnectivityService( context, mock(), mock(), netd, - deps).also { + deps, mPermDeps).also { it.mLingerDelayMs = TEST_LINGER_DELAY_MS it.mNascentDelayMs = TEST_NASCENT_DELAY_MS }