Check local network permissions when permission changes, or when user or
packages is added or removed Bug: 388803658 Test: atest ConnectivityCoverageTests Change-Id: I7d098c4d9a7614d0bd40ae23869a2010ee3f0779
This commit is contained in:
parent
37e457bd0a
commit
8d5c6eae80
8 changed files with 317 additions and 33 deletions
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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<T> {
|
||||
|
|
@ -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<PackageInfo> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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<Integer> 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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<DestroySocketsWrapper>()
|
||||
|
||||
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<PacProxyManager>()
|
||||
val networkPolicyManager = mock<NetworkPolicyManager>()
|
||||
|
|
|
|||
|
|
@ -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<IDnsResolver>(),
|
||||
mock<IpConnectivityLog>(),
|
||||
netd,
|
||||
deps).also {
|
||||
deps, mPermDeps).also {
|
||||
it.mLingerDelayMs = TEST_LINGER_DELAY_MS
|
||||
it.mNascentDelayMs = TEST_NASCENT_DELAY_MS
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue