blob: 76e3e2fced6ff5d87b91824d519fc50d4789804c [file] [log] [blame]
Chalard Jean26aa91a2018-03-20 19:13:57 +09001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.connectivity;
18
19import static android.Manifest.permission.CHANGE_NETWORK_STATE;
20import static android.Manifest.permission.CHANGE_WIFI_STATE;
21import static android.Manifest.permission.CONNECTIVITY_INTERNAL;
22import static android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS;
Chenbo Feng436fe582019-02-25 22:55:58 -080023import static android.Manifest.permission.INTERNET;
Chalard Jean26aa91a2018-03-20 19:13:57 +090024import static android.Manifest.permission.NETWORK_STACK;
Chenbo Feng436fe582019-02-25 22:55:58 -080025import static android.Manifest.permission.UPDATE_DEVICE_STATS;
paulhub6733802018-08-20 11:01:21 +080026import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_OEM;
27import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRODUCT;
28import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_VENDOR;
Chenbo Feng436fe582019-02-25 22:55:58 -080029import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_GRANTED;
paulhu86e23eb2019-11-05 18:05:05 +080030import static android.content.pm.PackageInfo.REQUESTED_PERMISSION_REQUIRED;
Chalard Jean26aa91a2018-03-20 19:13:57 +090031import static android.content.pm.PackageManager.GET_PERMISSIONS;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000032import static android.content.pm.PackageManager.MATCH_ANY_USER;
paulhu3b0f5ea2018-11-01 10:38:11 +080033import static android.os.Process.SYSTEM_UID;
Chalard Jean26aa91a2018-03-20 19:13:57 +090034
junyulai2454b692018-11-01 17:16:31 +080035import static com.android.server.connectivity.PermissionMonitor.NETWORK;
36import static com.android.server.connectivity.PermissionMonitor.SYSTEM;
37
38import static junit.framework.Assert.fail;
39
paulhu86e23eb2019-11-05 18:05:05 +080040import static org.junit.Assert.assertEquals;
Chalard Jean26aa91a2018-03-20 19:13:57 +090041import static org.junit.Assert.assertFalse;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000042import static org.junit.Assert.assertNull;
Chalard Jean26aa91a2018-03-20 19:13:57 +090043import static org.junit.Assert.assertTrue;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000044import static org.mockito.AdditionalMatchers.aryEq;
junyulai2454b692018-11-01 17:16:31 +080045import static org.mockito.ArgumentMatchers.any;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000046import static org.mockito.ArgumentMatchers.anyInt;
47import static org.mockito.ArgumentMatchers.anyString;
48import static org.mockito.ArgumentMatchers.eq;
junyulai2454b692018-11-01 17:16:31 +080049import static org.mockito.Mockito.doAnswer;
junyulai345155e2018-11-09 12:37:16 +080050import static org.mockito.Mockito.doReturn;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000051import static org.mockito.Mockito.reset;
junyulai345155e2018-11-09 12:37:16 +080052import static org.mockito.Mockito.spy;
Chenbo Feng436fe582019-02-25 22:55:58 -080053import static org.mockito.Mockito.verify;
Chalard Jean26aa91a2018-03-20 19:13:57 +090054import static org.mockito.Mockito.when;
55
56import android.content.Context;
57import android.content.pm.ApplicationInfo;
58import android.content.pm.PackageInfo;
Chenbo Feng436fe582019-02-25 22:55:58 -080059import android.content.pm.PackageList;
Chalard Jean26aa91a2018-03-20 19:13:57 +090060import android.content.pm.PackageManager;
Chenbo Feng436fe582019-02-25 22:55:58 -080061import android.content.pm.PackageManagerInternal;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000062import android.content.pm.UserInfo;
Chenbo Feng436fe582019-02-25 22:55:58 -080063import android.net.INetd;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000064import android.net.UidRange;
paulhub6733802018-08-20 11:01:21 +080065import android.os.Build;
junyulai2454b692018-11-01 17:16:31 +080066import android.os.UserHandle;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000067import android.os.UserManager;
Chenbo Feng436fe582019-02-25 22:55:58 -080068import android.util.SparseIntArray;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080069
Chalard Jean506686b2019-05-23 18:30:38 +090070import androidx.test.InstrumentationRegistry;
Brett Chabot1ae2aa62019-03-04 14:14:56 -080071import androidx.test.filters.SmallTest;
72import androidx.test.runner.AndroidJUnit4;
Chalard Jean26aa91a2018-03-20 19:13:57 +090073
Chenbo Feng436fe582019-02-25 22:55:58 -080074import com.android.server.LocalServices;
75
Chalard Jean26aa91a2018-03-20 19:13:57 +090076import org.junit.Before;
77import org.junit.Test;
78import org.junit.runner.RunWith;
Chenbo Feng436fe582019-02-25 22:55:58 -080079import org.mockito.ArgumentCaptor;
Chalard Jean26aa91a2018-03-20 19:13:57 +090080import org.mockito.Mock;
81import org.mockito.MockitoAnnotations;
junyulai2454b692018-11-01 17:16:31 +080082import org.mockito.invocation.InvocationOnMock;
83
Chenbo Feng436fe582019-02-25 22:55:58 -080084import java.util.ArrayList;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000085import java.util.Arrays;
86import java.util.Collections;
junyulai2454b692018-11-01 17:16:31 +080087import java.util.HashMap;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +000088import java.util.HashSet;
89import java.util.Set;
90
Chalard Jean26aa91a2018-03-20 19:13:57 +090091
92@RunWith(AndroidJUnit4.class)
93@SmallTest
94public class PermissionMonitorTest {
junyulai2454b692018-11-01 17:16:31 +080095 private static final int MOCK_USER1 = 0;
96 private static final int MOCK_USER2 = 1;
97 private static final int MOCK_UID1 = 10001;
Chenbo Feng436fe582019-02-25 22:55:58 -080098 private static final int MOCK_UID2 = 10086;
99 private static final int SYSTEM_UID1 = 1000;
100 private static final int SYSTEM_UID2 = 1008;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000101 private static final int VPN_UID = 10002;
Chalard Jean506686b2019-05-23 18:30:38 +0900102 private static final String REAL_SYSTEM_PACKAGE_NAME = "android";
junyulai2454b692018-11-01 17:16:31 +0800103 private static final String MOCK_PACKAGE1 = "appName1";
Chenbo Feng436fe582019-02-25 22:55:58 -0800104 private static final String MOCK_PACKAGE2 = "appName2";
junyulai2454b692018-11-01 17:16:31 +0800105 private static final String SYSTEM_PACKAGE1 = "sysName1";
106 private static final String SYSTEM_PACKAGE2 = "sysName2";
paulhub6733802018-08-20 11:01:21 +0800107 private static final String PARTITION_SYSTEM = "system";
108 private static final String PARTITION_OEM = "oem";
109 private static final String PARTITION_PRODUCT = "product";
110 private static final String PARTITION_VENDOR = "vendor";
paulhu3b0f5ea2018-11-01 10:38:11 +0800111 private static final int VERSION_P = Build.VERSION_CODES.P;
112 private static final int VERSION_Q = Build.VERSION_CODES.Q;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900113
114 @Mock private Context mContext;
115 @Mock private PackageManager mPackageManager;
Chenbo Feng436fe582019-02-25 22:55:58 -0800116 @Mock private INetd mNetdService;
117 @Mock private PackageManagerInternal mMockPmi;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000118 @Mock private UserManager mUserManager;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900119
Chenbo Feng436fe582019-02-25 22:55:58 -0800120 private PackageManagerInternal.PackageListObserver mObserver;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900121 private PermissionMonitor mPermissionMonitor;
122
123 @Before
124 public void setUp() throws Exception {
125 MockitoAnnotations.initMocks(this);
126 when(mContext.getPackageManager()).thenReturn(mPackageManager);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000127 when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
128 when(mUserManager.getUsers(eq(true))).thenReturn(
129 Arrays.asList(new UserInfo[] {
130 new UserInfo(MOCK_USER1, "", 0),
131 new UserInfo(MOCK_USER2, "", 0),
132 }));
133
134 mPermissionMonitor = spy(new PermissionMonitor(mContext, mNetdService));
Chenbo Feng436fe582019-02-25 22:55:58 -0800135
136 LocalServices.removeServiceForTest(PackageManagerInternal.class);
137 LocalServices.addService(PackageManagerInternal.class, mMockPmi);
138 when(mMockPmi.getPackageList(any())).thenReturn(new PackageList(new ArrayList<String>(),
139 /* observer */ null));
140 when(mPackageManager.getInstalledPackages(anyInt())).thenReturn(/* empty app list */ null);
141 mPermissionMonitor.startMonitoring();
142
143 final ArgumentCaptor<PackageManagerInternal.PackageListObserver> observerCaptor =
144 ArgumentCaptor.forClass(PackageManagerInternal.PackageListObserver.class);
145 verify(mMockPmi).getPackageList(observerCaptor.capture());
146 mObserver = observerCaptor.getValue();
Chalard Jean26aa91a2018-03-20 19:13:57 +0900147 }
148
paulhu86e23eb2019-11-05 18:05:05 +0800149 private boolean hasRestrictedNetworkPermission(String partition, int targetSdkVersion, int uid,
150 String... permissions) {
151 final PackageInfo packageInfo =
152 packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, permissions, partition);
paulhub6733802018-08-20 11:01:21 +0800153 packageInfo.applicationInfo.targetSdkVersion = targetSdkVersion;
paulhu3b0f5ea2018-11-01 10:38:11 +0800154 packageInfo.applicationInfo.uid = uid;
paulhu86e23eb2019-11-05 18:05:05 +0800155 return mPermissionMonitor.hasRestrictedNetworkPermission(packageInfo);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900156 }
157
paulhu86e23eb2019-11-05 18:05:05 +0800158 private static PackageInfo systemPackageInfoWithPermissions(String... permissions) {
159 return packageInfoWithPermissions(
160 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
161 }
162
163 private static PackageInfo vendorPackageInfoWithPermissions(String... permissions) {
164 return packageInfoWithPermissions(
165 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_VENDOR);
166 }
167
168 private static PackageInfo packageInfoWithPermissions(int permissionsFlags,
169 String[] permissions, String partition) {
Chenbo Feng436fe582019-02-25 22:55:58 -0800170 int[] requestedPermissionsFlags = new int[permissions.length];
171 for (int i = 0; i < permissions.length; i++) {
paulhu86e23eb2019-11-05 18:05:05 +0800172 requestedPermissionsFlags[i] = permissionsFlags;
Chenbo Feng436fe582019-02-25 22:55:58 -0800173 }
Chalard Jean26aa91a2018-03-20 19:13:57 +0900174 final PackageInfo packageInfo = new PackageInfo();
175 packageInfo.requestedPermissions = permissions;
176 packageInfo.applicationInfo = new ApplicationInfo();
Chenbo Feng436fe582019-02-25 22:55:58 -0800177 packageInfo.requestedPermissionsFlags = requestedPermissionsFlags;
paulhub6733802018-08-20 11:01:21 +0800178 int privateFlags = 0;
179 switch (partition) {
180 case PARTITION_OEM:
181 privateFlags = PRIVATE_FLAG_OEM;
182 break;
183 case PARTITION_PRODUCT:
184 privateFlags = PRIVATE_FLAG_PRODUCT;
185 break;
186 case PARTITION_VENDOR:
187 privateFlags = PRIVATE_FLAG_VENDOR;
188 break;
189 }
190 packageInfo.applicationInfo.privateFlags = privateFlags;
Chalard Jean26aa91a2018-03-20 19:13:57 +0900191 return packageInfo;
192 }
193
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000194 private static PackageInfo buildPackageInfo(boolean hasSystemPermission, int uid, int userId) {
195 final PackageInfo pkgInfo;
196 if (hasSystemPermission) {
paulhu86e23eb2019-11-05 18:05:05 +0800197 pkgInfo = systemPackageInfoWithPermissions(
198 CHANGE_NETWORK_STATE, NETWORK_STACK, CONNECTIVITY_USE_RESTRICTED_NETWORKS);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000199 } else {
paulhu86e23eb2019-11-05 18:05:05 +0800200 pkgInfo = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED, new String[] {}, "");
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000201 }
202 pkgInfo.applicationInfo.uid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
203 return pkgInfo;
204 }
205
Chalard Jean26aa91a2018-03-20 19:13:57 +0900206 @Test
207 public void testHasPermission() {
paulhu86e23eb2019-11-05 18:05:05 +0800208 PackageInfo app = systemPackageInfoWithPermissions();
Chalard Jean26aa91a2018-03-20 19:13:57 +0900209 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
210 assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
211 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
212 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
213
paulhu86e23eb2019-11-05 18:05:05 +0800214 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE, NETWORK_STACK);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900215 assertTrue(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
216 assertTrue(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
217 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
218 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
219
paulhu86e23eb2019-11-05 18:05:05 +0800220 app = systemPackageInfoWithPermissions(
221 CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900222 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
223 assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
224 assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
225 assertTrue(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
paulhu86e23eb2019-11-05 18:05:05 +0800226
227 app = packageInfoWithPermissions(REQUESTED_PERMISSION_REQUIRED, new String[] {
228 CONNECTIVITY_USE_RESTRICTED_NETWORKS, CONNECTIVITY_INTERNAL, NETWORK_STACK },
229 PARTITION_SYSTEM);
230 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
231 assertFalse(mPermissionMonitor.hasPermission(app, NETWORK_STACK));
232 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
233 assertFalse(mPermissionMonitor.hasPermission(app, CONNECTIVITY_INTERNAL));
234
235 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
236 app.requestedPermissions = null;
237 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
238
239 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
240 app.requestedPermissionsFlags = null;
241 assertFalse(mPermissionMonitor.hasPermission(app, CHANGE_NETWORK_STATE));
Chalard Jean26aa91a2018-03-20 19:13:57 +0900242 }
243
244 @Test
paulhub6733802018-08-20 11:01:21 +0800245 public void testIsVendorApp() {
paulhu86e23eb2019-11-05 18:05:05 +0800246 PackageInfo app = systemPackageInfoWithPermissions();
paulhub6733802018-08-20 11:01:21 +0800247 assertFalse(mPermissionMonitor.isVendorApp(app.applicationInfo));
paulhu86e23eb2019-11-05 18:05:05 +0800248 app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
249 new String[] {}, PARTITION_OEM);
paulhub6733802018-08-20 11:01:21 +0800250 assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
paulhu86e23eb2019-11-05 18:05:05 +0800251 app = packageInfoWithPermissions(REQUESTED_PERMISSION_GRANTED,
252 new String[] {}, PARTITION_PRODUCT);
paulhub6733802018-08-20 11:01:21 +0800253 assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
paulhu86e23eb2019-11-05 18:05:05 +0800254 app = vendorPackageInfoWithPermissions();
paulhub6733802018-08-20 11:01:21 +0800255 assertTrue(mPermissionMonitor.isVendorApp(app.applicationInfo));
Chalard Jean26aa91a2018-03-20 19:13:57 +0900256 }
257
258 @Test
paulhu86e23eb2019-11-05 18:05:05 +0800259 public void testHasNetworkPermission() {
260 PackageInfo app = systemPackageInfoWithPermissions();
261 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
262 app = systemPackageInfoWithPermissions(CHANGE_NETWORK_STATE);
263 assertTrue(mPermissionMonitor.hasNetworkPermission(app));
264 app = systemPackageInfoWithPermissions(NETWORK_STACK);
265 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
266 app = systemPackageInfoWithPermissions(CONNECTIVITY_USE_RESTRICTED_NETWORKS);
267 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
paulhu59148b72019-08-12 16:25:11 +0800268 app = systemPackageInfoWithPermissions(CONNECTIVITY_INTERNAL);
269 assertFalse(mPermissionMonitor.hasNetworkPermission(app));
paulhu86e23eb2019-11-05 18:05:05 +0800270 }
271
272 @Test
273 public void testHasRestrictedNetworkPermission() {
274 assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, MOCK_UID1));
275 assertFalse(hasRestrictedNetworkPermission(
276 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
277 assertTrue(hasRestrictedNetworkPermission(
278 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, NETWORK_STACK));
paulhu59148b72019-08-12 16:25:11 +0800279 assertFalse(hasRestrictedNetworkPermission(
paulhu86e23eb2019-11-05 18:05:05 +0800280 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
281 assertTrue(hasRestrictedNetworkPermission(
282 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
283 assertFalse(hasRestrictedNetworkPermission(
284 PARTITION_SYSTEM, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
285
286 assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, MOCK_UID1));
287 assertFalse(hasRestrictedNetworkPermission(
paulhu59148b72019-08-12 16:25:11 +0800288 PARTITION_SYSTEM, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
paulhu86e23eb2019-11-05 18:05:05 +0800289 }
290
291 @Test
292 public void testHasRestrictedNetworkPermissionSystemUid() {
293 doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt();
294 assertTrue(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID));
295 assertTrue(hasRestrictedNetworkPermission(
paulhu59148b72019-08-12 16:25:11 +0800296 PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_INTERNAL));
paulhu86e23eb2019-11-05 18:05:05 +0800297 assertTrue(hasRestrictedNetworkPermission(
298 PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
299
300 doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt();
301 assertFalse(hasRestrictedNetworkPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID));
302 assertFalse(hasRestrictedNetworkPermission(
paulhu59148b72019-08-12 16:25:11 +0800303 PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_INTERNAL));
paulhu86e23eb2019-11-05 18:05:05 +0800304 assertTrue(hasRestrictedNetworkPermission(
305 PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
306 }
307
308 @Test
309 public void testHasRestrictedNetworkPermissionVendorApp() {
310 assertTrue(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_P, MOCK_UID1));
311 assertTrue(hasRestrictedNetworkPermission(
312 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_NETWORK_STATE));
313 assertTrue(hasRestrictedNetworkPermission(
314 PARTITION_VENDOR, VERSION_P, MOCK_UID1, NETWORK_STACK));
315 assertTrue(hasRestrictedNetworkPermission(
316 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_INTERNAL));
317 assertTrue(hasRestrictedNetworkPermission(
318 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
319 assertTrue(hasRestrictedNetworkPermission(
320 PARTITION_VENDOR, VERSION_P, MOCK_UID1, CHANGE_WIFI_STATE));
321
322 assertFalse(hasRestrictedNetworkPermission(PARTITION_VENDOR, VERSION_Q, MOCK_UID1));
323 assertFalse(hasRestrictedNetworkPermission(
paulhu59148b72019-08-12 16:25:11 +0800324 PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CONNECTIVITY_INTERNAL));
paulhu86e23eb2019-11-05 18:05:05 +0800325 assertFalse(hasRestrictedNetworkPermission(
326 PARTITION_VENDOR, VERSION_Q, MOCK_UID1, CHANGE_NETWORK_STATE));
327 }
328
329 private void assertBackgroundPermission(boolean hasPermission, String name, int uid,
330 String... permissions) throws Exception {
331 when(mPackageManager.getPackageInfo(eq(name), anyInt()))
332 .thenReturn(packageInfoWithPermissions(
333 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM));
334 mPermissionMonitor.onPackageAdded(name, uid);
335 assertEquals(hasPermission, mPermissionMonitor.hasUseBackgroundNetworksPermission(uid));
336 }
337
338 @Test
Chalard Jean26aa91a2018-03-20 19:13:57 +0900339 public void testHasUseBackgroundNetworksPermission() throws Exception {
paulhu86e23eb2019-11-05 18:05:05 +0800340 assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(SYSTEM_UID));
341 assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID);
paulhu59148b72019-08-12 16:25:11 +0800342 assertBackgroundPermission(false, SYSTEM_PACKAGE1, SYSTEM_UID, CONNECTIVITY_INTERNAL);
paulhu86e23eb2019-11-05 18:05:05 +0800343 assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, CHANGE_NETWORK_STATE);
344 assertBackgroundPermission(true, SYSTEM_PACKAGE1, SYSTEM_UID, NETWORK_STACK);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900345
paulhu86e23eb2019-11-05 18:05:05 +0800346 assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID1));
347 assertBackgroundPermission(false, MOCK_PACKAGE1, MOCK_UID1);
348 assertBackgroundPermission(true, MOCK_PACKAGE1, MOCK_UID1,
349 CONNECTIVITY_USE_RESTRICTED_NETWORKS);
Chalard Jean26aa91a2018-03-20 19:13:57 +0900350
paulhu86e23eb2019-11-05 18:05:05 +0800351 assertFalse(mPermissionMonitor.hasUseBackgroundNetworksPermission(MOCK_UID2));
352 assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2);
paulhu59148b72019-08-12 16:25:11 +0800353 assertBackgroundPermission(false, MOCK_PACKAGE2, MOCK_UID2,
paulhu86e23eb2019-11-05 18:05:05 +0800354 CONNECTIVITY_INTERNAL);
paulhu59148b72019-08-12 16:25:11 +0800355 assertBackgroundPermission(true, MOCK_PACKAGE2, MOCK_UID2, NETWORK_STACK);
junyulai2454b692018-11-01 17:16:31 +0800356 }
357
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000358 private class NetdMonitor {
junyulai2454b692018-11-01 17:16:31 +0800359 private final HashMap<Integer, Boolean> mApps = new HashMap<>();
360
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000361 NetdMonitor(INetd mockNetd) throws Exception {
junyulai2454b692018-11-01 17:16:31 +0800362 // Add hook to verify and track result of setPermission.
363 doAnswer((InvocationOnMock invocation) -> {
364 final Object[] args = invocation.getArguments();
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000365 final Boolean isSystem = args[0].equals(INetd.PERMISSION_SYSTEM);
junyulai2454b692018-11-01 17:16:31 +0800366 for (final int uid : (int[]) args[1]) {
367 // TODO: Currently, permission monitor will send duplicate commands for each uid
368 // corresponding to each user. Need to fix that and uncomment below test.
369 // if (mApps.containsKey(uid) && mApps.get(uid) == isSystem) {
370 // fail("uid " + uid + " is already set to " + isSystem);
371 // }
372 mApps.put(uid, isSystem);
373 }
374 return null;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000375 }).when(mockNetd).networkSetPermissionForUser(anyInt(), any(int[].class));
junyulai2454b692018-11-01 17:16:31 +0800376
377 // Add hook to verify and track result of clearPermission.
378 doAnswer((InvocationOnMock invocation) -> {
379 final Object[] args = invocation.getArguments();
380 for (final int uid : (int[]) args[0]) {
381 // TODO: Currently, permission monitor will send duplicate commands for each uid
382 // corresponding to each user. Need to fix that and uncomment below test.
383 // if (!mApps.containsKey(uid)) {
384 // fail("uid " + uid + " does not exist.");
385 // }
386 mApps.remove(uid);
387 }
388 return null;
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000389 }).when(mockNetd).networkClearPermissionForUser(any(int[].class));
junyulai2454b692018-11-01 17:16:31 +0800390 }
391
392 public void expectPermission(Boolean permission, int[] users, int[] apps) {
393 for (final int user : users) {
394 for (final int app : apps) {
395 final int uid = UserHandle.getUid(user, app);
396 if (!mApps.containsKey(uid)) {
397 fail("uid " + uid + " does not exist.");
398 }
399 if (mApps.get(uid) != permission) {
400 fail("uid " + uid + " has wrong permission: " + permission);
401 }
402 }
403 }
404 }
405
406 public void expectNoPermission(int[] users, int[] apps) {
407 for (final int user : users) {
408 for (final int app : apps) {
409 final int uid = UserHandle.getUid(user, app);
410 if (mApps.containsKey(uid)) {
411 fail("uid " + uid + " has listed permissions, expected none.");
412 }
413 }
414 }
415 }
416 }
417
418 @Test
419 public void testUserAndPackageAddRemove() throws Exception {
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000420 final NetdMonitor mNetdMonitor = new NetdMonitor(mNetdService);
junyulai2454b692018-11-01 17:16:31 +0800421
422 // MOCK_UID1: MOCK_PACKAGE1 only has network permission.
423 // SYSTEM_UID: SYSTEM_PACKAGE1 has system permission.
424 // SYSTEM_UID: SYSTEM_PACKAGE2 only has network permission.
425 doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(eq(SYSTEM), anyString());
426 doReturn(SYSTEM).when(mPermissionMonitor).highestPermissionForUid(any(),
427 eq(SYSTEM_PACKAGE1));
428 doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
429 eq(SYSTEM_PACKAGE2));
430 doReturn(NETWORK).when(mPermissionMonitor).highestPermissionForUid(any(),
431 eq(MOCK_PACKAGE1));
432
433 // Add SYSTEM_PACKAGE2, expect only have network permission.
434 mPermissionMonitor.onUserAdded(MOCK_USER1);
435 addPackageForUsers(new int[]{MOCK_USER1}, SYSTEM_PACKAGE2, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000436 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1}, new int[]{SYSTEM_UID});
junyulai2454b692018-11-01 17:16:31 +0800437
438 // Add SYSTEM_PACKAGE1, expect permission escalate.
439 addPackageForUsers(new int[]{MOCK_USER1}, SYSTEM_PACKAGE1, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000440 mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1}, new int[]{SYSTEM_UID});
junyulai2454b692018-11-01 17:16:31 +0800441
442 mPermissionMonitor.onUserAdded(MOCK_USER2);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000443 mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800444 new int[]{SYSTEM_UID});
445
446 addPackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_PACKAGE1, MOCK_UID1);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000447 mNetdMonitor.expectPermission(SYSTEM, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800448 new int[]{SYSTEM_UID});
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000449 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800450 new int[]{MOCK_UID1});
451
452 // Remove MOCK_UID1, expect no permission left for all user.
453 mPermissionMonitor.onPackageRemoved(MOCK_UID1);
454 removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, MOCK_UID1);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000455 mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2}, new int[]{MOCK_UID1});
junyulai2454b692018-11-01 17:16:31 +0800456
457 // Remove SYSTEM_PACKAGE1, expect permission downgrade.
458 when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{SYSTEM_PACKAGE2});
459 removePackageForUsers(new int[]{MOCK_USER1, MOCK_USER2}, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000460 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800461 new int[]{SYSTEM_UID});
462
463 mPermissionMonitor.onUserRemoved(MOCK_USER1);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000464 mNetdMonitor.expectPermission(NETWORK, new int[]{MOCK_USER2}, new int[]{SYSTEM_UID});
junyulai2454b692018-11-01 17:16:31 +0800465
466 // Remove all packages, expect no permission left.
467 when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(new String[]{});
468 removePackageForUsers(new int[]{MOCK_USER2}, SYSTEM_UID);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000469 mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800470 new int[]{SYSTEM_UID, MOCK_UID1});
471
472 // Remove last user, expect no redundant clearPermission is invoked.
473 mPermissionMonitor.onUserRemoved(MOCK_USER2);
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000474 mNetdMonitor.expectNoPermission(new int[]{MOCK_USER1, MOCK_USER2},
junyulai2454b692018-11-01 17:16:31 +0800475 new int[]{SYSTEM_UID, MOCK_UID1});
476 }
477
Lorenzo Colitti4c9f9542019-04-12 10:48:06 +0000478 @Test
479 public void testUidFilteringDuringVpnConnectDisconnectAndUidUpdates() throws Exception {
480 when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
481 Arrays.asList(new PackageInfo[] {
482 buildPackageInfo(/* SYSTEM */ true, SYSTEM_UID1, MOCK_USER1),
483 buildPackageInfo(/* SYSTEM */ false, MOCK_UID1, MOCK_USER1),
484 buildPackageInfo(/* SYSTEM */ false, MOCK_UID2, MOCK_USER1),
485 buildPackageInfo(/* SYSTEM */ false, VPN_UID, MOCK_USER1)
486 }));
487 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
488 buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
489 mPermissionMonitor.startMonitoring();
490 // Every app on user 0 except MOCK_UID2 are under VPN.
491 final Set<UidRange> vpnRange1 = new HashSet<>(Arrays.asList(new UidRange[] {
492 new UidRange(0, MOCK_UID2 - 1),
493 new UidRange(MOCK_UID2 + 1, UserHandle.PER_USER_RANGE - 1)}));
494 final Set<UidRange> vpnRange2 = Collections.singleton(new UidRange(MOCK_UID2, MOCK_UID2));
495
496 // When VPN is connected, expect a rule to be set up for user app MOCK_UID1
497 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange1, VPN_UID);
498 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
499 aryEq(new int[] {MOCK_UID1}));
500
501 reset(mNetdService);
502
503 // When MOCK_UID1 package is uninstalled and reinstalled, expect Netd to be updated
504 mPermissionMonitor.onPackageRemoved(UserHandle.getUid(MOCK_USER1, MOCK_UID1));
505 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
506 mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
507 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
508 aryEq(new int[] {MOCK_UID1}));
509
510 reset(mNetdService);
511
512 // During VPN uid update (vpnRange1 -> vpnRange2), ConnectivityService first deletes the
513 // old UID rules then adds the new ones. Expect netd to be updated
514 mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange1, VPN_UID);
515 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
516 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange2, VPN_UID);
517 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
518 aryEq(new int[] {MOCK_UID2}));
519
520 reset(mNetdService);
521
522 // When VPN is disconnected, expect rules to be torn down
523 mPermissionMonitor.onVpnUidRangesRemoved("tun0", vpnRange2, VPN_UID);
524 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID2}));
525 assertNull(mPermissionMonitor.getVpnUidRanges("tun0"));
526 }
527
528 @Test
529 public void testUidFilteringDuringPackageInstallAndUninstall() throws Exception {
530 when(mPackageManager.getInstalledPackages(eq(GET_PERMISSIONS | MATCH_ANY_USER))).thenReturn(
531 Arrays.asList(new PackageInfo[] {
532 buildPackageInfo(true, SYSTEM_UID1, MOCK_USER1),
533 buildPackageInfo(false, VPN_UID, MOCK_USER1)
534 }));
535 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE1), eq(GET_PERMISSIONS))).thenReturn(
536 buildPackageInfo(false, MOCK_UID1, MOCK_USER1));
537
538 mPermissionMonitor.startMonitoring();
539 final Set<UidRange> vpnRange = Collections.singleton(UidRange.createForUser(MOCK_USER1));
540 mPermissionMonitor.onVpnUidRangesAdded("tun0", vpnRange, VPN_UID);
541
542 // Newly-installed package should have uid rules added
543 mPermissionMonitor.onPackageAdded(MOCK_PACKAGE1, UserHandle.getUid(MOCK_USER1, MOCK_UID1));
544 verify(mNetdService).firewallAddUidInterfaceRules(eq("tun0"),
545 aryEq(new int[] {MOCK_UID1}));
546
547 // Removed package should have its uid rules removed
548 mPermissionMonitor.onPackageRemoved(UserHandle.getUid(MOCK_USER1, MOCK_UID1));
549 verify(mNetdService).firewallRemoveUidInterfaceRules(aryEq(new int[] {MOCK_UID1}));
550 }
551
552
junyulai2454b692018-11-01 17:16:31 +0800553 // Normal package add/remove operations will trigger multiple intent for uids corresponding to
554 // each user. To simulate generic package operations, the onPackageAdded/Removed will need to be
555 // called multiple times with the uid corresponding to each user.
556 private void addPackageForUsers(int[] users, String packageName, int uid) {
557 for (final int user : users) {
558 mPermissionMonitor.onPackageAdded(packageName, UserHandle.getUid(user, uid));
559 }
560 }
561
562 private void removePackageForUsers(int[] users, int uid) {
563 for (final int user : users) {
564 mPermissionMonitor.onPackageRemoved(UserHandle.getUid(user, uid));
565 }
Chalard Jean26aa91a2018-03-20 19:13:57 +0900566 }
Chenbo Feng436fe582019-02-25 22:55:58 -0800567
568 private class NetdServiceMonitor {
569 private final HashMap<Integer, Integer> mPermissions = new HashMap<>();
570
571 NetdServiceMonitor(INetd mockNetdService) throws Exception {
572 // Add hook to verify and track result of setPermission.
573 doAnswer((InvocationOnMock invocation) -> {
574 final Object[] args = invocation.getArguments();
575 final int permission = (int) args[0];
576 for (final int uid : (int[]) args[1]) {
577 mPermissions.put(uid, permission);
578 }
579 return null;
580 }).when(mockNetdService).trafficSetNetPermForUids(anyInt(), any(int[].class));
581 }
582
583 public void expectPermission(int permission, int[] apps) {
584 for (final int app : apps) {
585 if (!mPermissions.containsKey(app)) {
586 fail("uid " + app + " does not exist.");
587 }
588 if (mPermissions.get(app) != permission) {
589 fail("uid " + app + " has wrong permission: " + mPermissions.get(app));
590 }
591 }
592 }
593 }
594
595 @Test
596 public void testPackagePermissionUpdate() throws Exception {
597 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
598 // MOCK_UID1: MOCK_PACKAGE1 only has internet permission.
599 // MOCK_UID2: MOCK_PACKAGE2 does not have any permission.
600 // SYSTEM_UID1: SYSTEM_PACKAGE1 has internet permission and update device stats permission.
601 // SYSTEM_UID2: SYSTEM_PACKAGE2 has only update device stats permission.
602
603 SparseIntArray netdPermissionsAppIds = new SparseIntArray();
604 netdPermissionsAppIds.put(MOCK_UID1, INetd.PERMISSION_INTERNET);
Chenbo Feng05887f92019-04-19 16:05:03 -0700605 netdPermissionsAppIds.put(MOCK_UID2, INetd.PERMISSION_NONE);
Chenbo Feng436fe582019-02-25 22:55:58 -0800606 netdPermissionsAppIds.put(SYSTEM_UID1, INetd.PERMISSION_INTERNET
607 | INetd.PERMISSION_UPDATE_DEVICE_STATS);
608 netdPermissionsAppIds.put(SYSTEM_UID2, INetd.PERMISSION_UPDATE_DEVICE_STATS);
609
610 // Send the permission information to netd, expect permission updated.
611 mPermissionMonitor.sendPackagePermissionsToNetd(netdPermissionsAppIds);
612
613 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET,
614 new int[]{MOCK_UID1});
Chenbo Feng05887f92019-04-19 16:05:03 -0700615 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID2});
Chenbo Feng436fe582019-02-25 22:55:58 -0800616 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
617 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{SYSTEM_UID1});
618 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UPDATE_DEVICE_STATS,
619 new int[]{SYSTEM_UID2});
620
621 // Update permission of MOCK_UID1, expect new permission show up.
622 mPermissionMonitor.sendPackagePermissionsForUid(MOCK_UID1,
623 INetd.PERMISSION_INTERNET | INetd.PERMISSION_UPDATE_DEVICE_STATS);
624 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
625 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
626
627 // Change permissions of SYSTEM_UID2, expect new permission show up and old permission
628 // revoked.
629 mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID2,
630 INetd.PERMISSION_INTERNET);
631 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{SYSTEM_UID2});
632
633 // Revoke permission from SYSTEM_UID1, expect no permission stored.
Chenbo Feng05887f92019-04-19 16:05:03 -0700634 mPermissionMonitor.sendPackagePermissionsForUid(SYSTEM_UID1, INetd.PERMISSION_NONE);
635 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
Chenbo Feng436fe582019-02-25 22:55:58 -0800636 }
637
Lorenzo Colittifc901152019-09-20 11:36:06 +0900638 private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
Chenbo Feng436fe582019-02-25 22:55:58 -0800639 throws Exception {
paulhu86e23eb2019-11-05 18:05:05 +0800640 PackageInfo packageInfo = packageInfoWithPermissions(
641 REQUESTED_PERMISSION_GRANTED, permissions, PARTITION_SYSTEM);
Chenbo Feng436fe582019-02-25 22:55:58 -0800642 when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
643 when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
Lorenzo Colittifc901152019-09-20 11:36:06 +0900644 return packageInfo;
645 }
646
647 private PackageInfo addPackage(String packageName, int uid, String[] permissions)
648 throws Exception {
649 PackageInfo packageInfo = setPackagePermissions(packageName, uid, permissions);
Chenbo Feng436fe582019-02-25 22:55:58 -0800650 mObserver.onPackageAdded(packageName, uid);
651 return packageInfo;
652 }
653
654 @Test
655 public void testPackageInstall() throws Exception {
656 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
657
658 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
659 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
660 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
661
662 addPackage(MOCK_PACKAGE2, MOCK_UID2, new String[] {INTERNET});
663 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID2});
664 }
665
666 @Test
667 public void testPackageInstallSharedUid() throws Exception {
668 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
669
670 PackageInfo packageInfo1 = addPackage(MOCK_PACKAGE1, MOCK_UID1,
671 new String[] {INTERNET, UPDATE_DEVICE_STATS});
672 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
673 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
674
675 // Install another package with the same uid and no permissions should not cause the UID to
676 // lose permissions.
paulhu86e23eb2019-11-05 18:05:05 +0800677 PackageInfo packageInfo2 = systemPackageInfoWithPermissions();
Chenbo Feng436fe582019-02-25 22:55:58 -0800678 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
679 when(mPackageManager.getPackagesForUid(MOCK_UID1))
680 .thenReturn(new String[]{MOCK_PACKAGE1, MOCK_PACKAGE2});
681 mObserver.onPackageAdded(MOCK_PACKAGE2, MOCK_UID1);
682 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
683 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
684 }
685
686 @Test
687 public void testPackageUninstallBasic() throws Exception {
688 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
689
690 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
691 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
692 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
693
694 when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
695 mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
Chenbo Fenga6817cd2019-03-25 18:13:34 -0700696 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
Chenbo Feng436fe582019-02-25 22:55:58 -0800697 }
698
699 @Test
Lorenzo Colittifc901152019-09-20 11:36:06 +0900700 public void testPackageRemoveThenAdd() throws Exception {
Chenbo Feng436fe582019-02-25 22:55:58 -0800701 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
702
703 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
704 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
705 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
706
Chenbo Feng436fe582019-02-25 22:55:58 -0800707 when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
708 mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
Chenbo Fenga6817cd2019-03-25 18:13:34 -0700709 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
Chenbo Feng436fe582019-02-25 22:55:58 -0800710
711 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
712 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
713 }
714
715 @Test
Lorenzo Colittifc901152019-09-20 11:36:06 +0900716 public void testPackageUpdate() throws Exception {
717 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
718
719 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {});
720 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
721
722 // When updating a package, the broadcast receiver gets two broadcasts (a remove and then an
723 // add), but the observer sees only one callback (an update).
724 setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
725 mObserver.onPackageChanged(MOCK_PACKAGE1, MOCK_UID1);
726 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
727 }
728
729 @Test
Chenbo Feng436fe582019-02-25 22:55:58 -0800730 public void testPackageUninstallWithMultiplePackages() throws Exception {
731 final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
732
733 addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
734 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
735 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
736
737 // Mock another package with the same uid but different permissions.
paulhu86e23eb2019-11-05 18:05:05 +0800738 PackageInfo packageInfo2 = systemPackageInfoWithPermissions(INTERNET);
Chenbo Feng436fe582019-02-25 22:55:58 -0800739 when(mPackageManager.getPackageInfo(eq(MOCK_PACKAGE2), anyInt())).thenReturn(packageInfo2);
740 when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{
741 MOCK_PACKAGE2});
742
743 mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
744 mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
745 }
Chalard Jean506686b2019-05-23 18:30:38 +0900746
747 @Test
748 public void testRealSystemPermission() throws Exception {
749 // Use the real context as this test must ensure the *real* system package holds the
750 // necessary permission.
751 final Context realContext = InstrumentationRegistry.getContext();
752 final PermissionMonitor monitor = new PermissionMonitor(realContext, mNetdService);
753 final PackageManager manager = realContext.getPackageManager();
754 final PackageInfo systemInfo = manager.getPackageInfo(REAL_SYSTEM_PACKAGE_NAME,
755 GET_PERMISSIONS | MATCH_ANY_USER);
756 assertTrue(monitor.hasPermission(systemInfo, CONNECTIVITY_USE_RESTRICTED_NETWORKS));
757 }
Chalard Jean26aa91a2018-03-20 19:13:57 +0900758}