1 /* 2 * Copyright (C) 2022 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 17 package com.android.server; 18 19 import static android.net.BpfNetMapsConstants.ALLOW_CHAINS; 20 import static android.net.BpfNetMapsConstants.BACKGROUND_MATCH; 21 import static android.net.BpfNetMapsConstants.CURRENT_STATS_MAP_CONFIGURATION_KEY; 22 import static android.net.BpfNetMapsConstants.DATA_SAVER_ENABLED_KEY; 23 import static android.net.BpfNetMapsConstants.DATA_SAVER_DISABLED; 24 import static android.net.BpfNetMapsConstants.DATA_SAVER_ENABLED; 25 import static android.net.BpfNetMapsConstants.DENY_CHAINS; 26 import static android.net.BpfNetMapsConstants.DOZABLE_MATCH; 27 import static android.net.BpfNetMapsConstants.HAPPY_BOX_MATCH; 28 import static android.net.BpfNetMapsConstants.IIF_MATCH; 29 import static android.net.BpfNetMapsConstants.LOCKDOWN_VPN_MATCH; 30 import static android.net.BpfNetMapsConstants.LOW_POWER_STANDBY_MATCH; 31 import static android.net.BpfNetMapsConstants.NO_MATCH; 32 import static android.net.BpfNetMapsConstants.OEM_DENY_1_MATCH; 33 import static android.net.BpfNetMapsConstants.OEM_DENY_2_MATCH; 34 import static android.net.BpfNetMapsConstants.OEM_DENY_3_MATCH; 35 import static android.net.BpfNetMapsConstants.PENALTY_BOX_ADMIN_MATCH; 36 import static android.net.BpfNetMapsConstants.PENALTY_BOX_USER_MATCH; 37 import static android.net.BpfNetMapsConstants.POWERSAVE_MATCH; 38 import static android.net.BpfNetMapsConstants.RESTRICTED_MATCH; 39 import static android.net.BpfNetMapsConstants.STANDBY_MATCH; 40 import static android.net.BpfNetMapsConstants.UID_RULES_CONFIGURATION_KEY; 41 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_ADMIN_DISABLED; 42 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_DATA_SAVER; 43 import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_USER_RESTRICTED; 44 import static android.net.ConnectivityManager.BLOCKED_REASON_APP_STANDBY; 45 import static android.net.ConnectivityManager.BLOCKED_REASON_BATTERY_SAVER; 46 import static android.net.ConnectivityManager.BLOCKED_REASON_DOZE; 47 import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; 48 import static android.net.ConnectivityManager.BLOCKED_REASON_OEM_DENY; 49 import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; 50 import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; 51 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW; 52 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_ADMIN; 53 import static android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER; 54 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; 55 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_2; 56 import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3; 57 import static android.net.ConnectivityManager.FIREWALL_CHAIN_POWERSAVE; 58 import static android.net.ConnectivityManager.FIREWALL_CHAIN_RESTRICTED; 59 import static android.net.ConnectivityManager.FIREWALL_CHAIN_STANDBY; 60 import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; 61 import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; 62 import static android.net.INetd.PERMISSION_INTERNET; 63 import static android.net.INetd.PERMISSION_NONE; 64 import static android.net.INetd.PERMISSION_UNINSTALLED; 65 import static android.net.INetd.PERMISSION_UPDATE_DEVICE_STATS; 66 import static android.system.OsConstants.EINVAL; 67 import static android.system.OsConstants.EPERM; 68 69 import static com.android.server.ConnectivityStatsLog.NETWORK_BPF_MAP_INFO; 70 71 import static org.junit.Assert.assertEquals; 72 import static org.junit.Assert.assertFalse; 73 import static org.junit.Assert.assertNull; 74 import static org.junit.Assert.assertThrows; 75 import static org.junit.Assert.assertTrue; 76 import static org.junit.Assume.assumeFalse; 77 import static org.mockito.Mockito.any; 78 import static org.mockito.Mockito.doReturn; 79 import static org.mockito.Mockito.doThrow; 80 import static org.mockito.Mockito.spy; 81 import static org.mockito.Mockito.verify; 82 83 import android.app.StatsManager; 84 import android.content.Context; 85 import android.net.BpfNetMapsUtils; 86 import android.net.INetd; 87 import android.net.InetAddresses; 88 import android.net.UidOwnerValue; 89 import android.os.Build; 90 import android.os.Process; 91 import android.os.ServiceSpecificException; 92 import android.os.UserHandle; 93 import android.system.ErrnoException; 94 import android.util.ArraySet; 95 import android.util.IndentingPrintWriter; 96 97 import androidx.test.filters.SmallTest; 98 99 import com.android.modules.utils.build.SdkLevel; 100 import com.android.net.module.util.IBpfMap; 101 import com.android.net.module.util.Struct.S32; 102 import com.android.net.module.util.Struct.U32; 103 import com.android.net.module.util.Struct.U8; 104 import com.android.net.module.util.bpf.CookieTagMapKey; 105 import com.android.net.module.util.bpf.CookieTagMapValue; 106 import com.android.net.module.util.bpf.IngressDiscardKey; 107 import com.android.net.module.util.bpf.IngressDiscardValue; 108 import com.android.testutils.DevSdkIgnoreRule; 109 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter; 110 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 111 import com.android.testutils.DevSdkIgnoreRunner; 112 import com.android.testutils.TestBpfMap; 113 114 import org.junit.Before; 115 import org.junit.Rule; 116 import org.junit.Test; 117 import org.junit.runner.RunWith; 118 import org.mockito.Mock; 119 import org.mockito.MockitoAnnotations; 120 121 import java.io.FileDescriptor; 122 import java.io.StringWriter; 123 import java.net.Inet4Address; 124 import java.net.Inet6Address; 125 import java.util.ArrayList; 126 import java.util.List; 127 128 @RunWith(DevSdkIgnoreRunner.class) 129 @SmallTest 130 @DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.R) 131 public final class BpfNetMapsTest { 132 private static final String TAG = "BpfNetMapsTest"; 133 134 @Rule 135 public final DevSdkIgnoreRule ignoreRule = new DevSdkIgnoreRule(); 136 137 private static final int TEST_UID = 10086; 138 private static final int[] TEST_UIDS = {10002, 10003}; 139 private static final String TEST_IF_NAME = "wlan0"; 140 private static final int TEST_IF_INDEX = 7; 141 private static final int NO_IIF = 0; 142 private static final int NULL_IIF = 0; 143 private static final Inet4Address TEST_V4_ADDRESS = 144 (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.1"); 145 private static final Inet6Address TEST_V6_ADDRESS = 146 (Inet6Address) InetAddresses.parseNumericAddress("2001:db8::1"); 147 private static final String CHAINNAME = "fw_dozable"; 148 149 private static final long STATS_SELECT_MAP_A = 0; 150 private static final long STATS_SELECT_MAP_B = 1; 151 152 private static final List<Integer> FIREWALL_CHAINS = new ArrayList<>(); 153 static { 154 FIREWALL_CHAINS.addAll(ALLOW_CHAINS); 155 FIREWALL_CHAINS.addAll(DENY_CHAINS); 156 } 157 158 private BpfNetMaps mBpfNetMaps; 159 160 @Mock INetd mNetd; 161 @Mock BpfNetMaps.Dependencies mDeps; 162 @Mock Context mContext; 163 private final IBpfMap<S32, U32> mConfigurationMap = new TestBpfMap<>(S32.class, U32.class); 164 private final IBpfMap<S32, UidOwnerValue> mUidOwnerMap = 165 new TestBpfMap<>(S32.class, UidOwnerValue.class); 166 private final IBpfMap<S32, U8> mUidPermissionMap = new TestBpfMap<>(S32.class, U8.class); 167 private final IBpfMap<CookieTagMapKey, CookieTagMapValue> mCookieTagMap = 168 spy(new TestBpfMap<>(CookieTagMapKey.class, CookieTagMapValue.class)); 169 private final IBpfMap<S32, U8> mDataSaverEnabledMap = new TestBpfMap<>(S32.class, U8.class); 170 private final IBpfMap<IngressDiscardKey, IngressDiscardValue> mIngressDiscardMap = 171 new TestBpfMap<>(IngressDiscardKey.class, IngressDiscardValue.class); 172 173 @Before setUp()174 public void setUp() throws Exception { 175 MockitoAnnotations.initMocks(this); 176 doReturn(TEST_IF_INDEX).when(mDeps).getIfIndex(TEST_IF_NAME); 177 doReturn(TEST_IF_NAME).when(mDeps).getIfName(TEST_IF_INDEX); 178 doReturn(0).when(mDeps).synchronizeKernelRCU(); 179 BpfNetMaps.setConfigurationMapForTest(mConfigurationMap); 180 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0)); 181 mConfigurationMap.updateEntry( 182 CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_A)); 183 BpfNetMaps.setUidOwnerMapForTest(mUidOwnerMap); 184 BpfNetMaps.setUidPermissionMapForTest(mUidPermissionMap); 185 BpfNetMaps.setCookieTagMapForTest(mCookieTagMap); 186 BpfNetMaps.setDataSaverEnabledMapForTest(mDataSaverEnabledMap); 187 mDataSaverEnabledMap.updateEntry(DATA_SAVER_ENABLED_KEY, new U8(DATA_SAVER_DISABLED)); 188 BpfNetMaps.setIngressDiscardMapForTest(mIngressDiscardMap); 189 mBpfNetMaps = new BpfNetMaps(mContext, mNetd, mDeps); 190 } 191 192 @Test testBpfNetMapsBeforeT()193 public void testBpfNetMapsBeforeT() throws Exception { 194 assumeFalse(SdkLevel.isAtLeastT()); 195 mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS); 196 verify(mNetd).firewallAddUidInterfaceRules(TEST_IF_NAME, TEST_UIDS); 197 mBpfNetMaps.removeUidInterfaceRules(TEST_UIDS); 198 verify(mNetd).firewallRemoveUidInterfaceRules(TEST_UIDS); 199 mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS); 200 verify(mNetd).trafficSetNetPermForUids(PERMISSION_INTERNET, TEST_UIDS); 201 } 202 getMatch(final List<Integer> chains)203 private long getMatch(final List<Integer> chains) { 204 long match = 0; 205 for (final int chain: chains) { 206 match |= BpfNetMapsUtils.getMatchByFirewallChain(chain); 207 } 208 return match; 209 } 210 doTestIsChainEnabled(final List<Integer> enableChains)211 private void doTestIsChainEnabled(final List<Integer> enableChains) throws Exception { 212 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(getMatch(enableChains))); 213 214 for (final int chain: FIREWALL_CHAINS) { 215 final String testCase = "EnabledChains: " + enableChains + " CheckedChain: " + chain; 216 if (enableChains.contains(chain)) { 217 assertTrue("Expected isChainEnabled returns True, " + testCase, 218 mBpfNetMaps.isChainEnabled(chain)); 219 } else { 220 assertFalse("Expected isChainEnabled returns False, " + testCase, 221 mBpfNetMaps.isChainEnabled(chain)); 222 } 223 } 224 } 225 doTestIsChainEnabled(final int enableChain)226 private void doTestIsChainEnabled(final int enableChain) throws Exception { 227 doTestIsChainEnabled(List.of(enableChain)); 228 } 229 230 @Test 231 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testIsChainEnabled()232 public void testIsChainEnabled() throws Exception { 233 doTestIsChainEnabled(FIREWALL_CHAIN_DOZABLE); 234 doTestIsChainEnabled(FIREWALL_CHAIN_STANDBY); 235 doTestIsChainEnabled(FIREWALL_CHAIN_POWERSAVE); 236 doTestIsChainEnabled(FIREWALL_CHAIN_RESTRICTED); 237 doTestIsChainEnabled(FIREWALL_CHAIN_LOW_POWER_STANDBY); 238 doTestIsChainEnabled(FIREWALL_CHAIN_OEM_DENY_1); 239 doTestIsChainEnabled(FIREWALL_CHAIN_OEM_DENY_2); 240 doTestIsChainEnabled(FIREWALL_CHAIN_OEM_DENY_3); 241 } 242 243 @Test 244 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testIsChainEnabledMultipleChainEnabled()245 public void testIsChainEnabledMultipleChainEnabled() throws Exception { 246 doTestIsChainEnabled(List.of( 247 FIREWALL_CHAIN_DOZABLE, 248 FIREWALL_CHAIN_STANDBY)); 249 doTestIsChainEnabled(List.of( 250 FIREWALL_CHAIN_DOZABLE, 251 FIREWALL_CHAIN_STANDBY, 252 FIREWALL_CHAIN_POWERSAVE, 253 FIREWALL_CHAIN_RESTRICTED)); 254 doTestIsChainEnabled(FIREWALL_CHAINS); 255 } 256 257 @Test 258 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testIsChainEnabledInvalidChain()259 public void testIsChainEnabledInvalidChain() { 260 final Class<ServiceSpecificException> expected = ServiceSpecificException.class; 261 assertThrows(expected, () -> mBpfNetMaps.isChainEnabled(-1 /* childChain */)); 262 assertThrows(expected, () -> mBpfNetMaps.isChainEnabled(1000 /* childChain */)); 263 } 264 265 @Test 266 @IgnoreAfter(Build.VERSION_CODES.S_V2) testIsChainEnabledBeforeT()267 public void testIsChainEnabledBeforeT() { 268 assertThrows(UnsupportedOperationException.class, 269 () -> mBpfNetMaps.isChainEnabled(FIREWALL_CHAIN_DOZABLE)); 270 } 271 doTestSetChildChain(final List<Integer> testChains)272 private void doTestSetChildChain(final List<Integer> testChains) throws Exception { 273 long expectedMatch = 0; 274 for (final int chain: testChains) { 275 expectedMatch |= BpfNetMapsUtils.getMatchByFirewallChain(chain); 276 } 277 278 assertEquals(0, mConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val); 279 280 for (final int chain: testChains) { 281 mBpfNetMaps.setChildChain(chain, true /* enable */); 282 } 283 assertEquals(expectedMatch, mConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val); 284 285 for (final int chain: testChains) { 286 mBpfNetMaps.setChildChain(chain, false /* enable */); 287 } 288 assertEquals(0, mConfigurationMap.getValue(UID_RULES_CONFIGURATION_KEY).val); 289 } 290 doTestSetChildChain(final int testChain)291 private void doTestSetChildChain(final int testChain) throws Exception { 292 doTestSetChildChain(List.of(testChain)); 293 } 294 295 @Test 296 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetChildChain()297 public void testSetChildChain() throws Exception { 298 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0)); 299 doTestSetChildChain(FIREWALL_CHAIN_DOZABLE); 300 doTestSetChildChain(FIREWALL_CHAIN_STANDBY); 301 doTestSetChildChain(FIREWALL_CHAIN_POWERSAVE); 302 doTestSetChildChain(FIREWALL_CHAIN_RESTRICTED); 303 doTestSetChildChain(FIREWALL_CHAIN_LOW_POWER_STANDBY); 304 doTestSetChildChain(FIREWALL_CHAIN_OEM_DENY_1); 305 doTestSetChildChain(FIREWALL_CHAIN_OEM_DENY_2); 306 doTestSetChildChain(FIREWALL_CHAIN_OEM_DENY_3); 307 } 308 309 @Test 310 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetChildChainMultipleChain()311 public void testSetChildChainMultipleChain() throws Exception { 312 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(0)); 313 doTestSetChildChain(List.of( 314 FIREWALL_CHAIN_DOZABLE, 315 FIREWALL_CHAIN_STANDBY)); 316 doTestSetChildChain(List.of( 317 FIREWALL_CHAIN_DOZABLE, 318 FIREWALL_CHAIN_STANDBY, 319 FIREWALL_CHAIN_POWERSAVE, 320 FIREWALL_CHAIN_RESTRICTED)); 321 doTestSetChildChain(FIREWALL_CHAINS); 322 } 323 324 @Test 325 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetChildChainInvalidChain()326 public void testSetChildChainInvalidChain() { 327 final Class<ServiceSpecificException> expected = ServiceSpecificException.class; 328 assertThrows(expected, 329 () -> mBpfNetMaps.setChildChain(-1 /* childChain */, true /* enable */)); 330 assertThrows(expected, 331 () -> mBpfNetMaps.setChildChain(1000 /* childChain */, true /* enable */)); 332 } 333 334 @Test 335 @IgnoreAfter(Build.VERSION_CODES.S_V2) testSetChildChainBeforeT()336 public void testSetChildChainBeforeT() { 337 assertThrows(UnsupportedOperationException.class, 338 () -> mBpfNetMaps.setChildChain(FIREWALL_CHAIN_DOZABLE, true /* enable */)); 339 } 340 checkUidOwnerValue(final int uid, final int expectedIif, final long expectedMatch)341 private void checkUidOwnerValue(final int uid, final int expectedIif, 342 final long expectedMatch) throws Exception { 343 final UidOwnerValue config = mUidOwnerMap.getValue(new S32(uid)); 344 if (expectedMatch == 0) { 345 assertNull(config); 346 } else { 347 assertEquals(expectedIif, config.iif); 348 assertEquals(expectedMatch, config.rule); 349 } 350 } 351 doTestUpdateUidLockdownRule(final int iif, final long match, final boolean add)352 private void doTestUpdateUidLockdownRule(final int iif, final long match, final boolean add) 353 throws Exception { 354 if (match != NO_MATCH) { 355 mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match)); 356 } 357 358 mBpfNetMaps.updateUidLockdownRule(TEST_UID, add); 359 360 final long expectedMatch = add ? match | LOCKDOWN_VPN_MATCH : match & ~LOCKDOWN_VPN_MATCH; 361 checkUidOwnerValue(TEST_UID, iif, expectedMatch); 362 } 363 364 private static final boolean ADD = true; 365 private static final boolean REMOVE = false; 366 367 @Test 368 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testUpdateUidLockdownRuleAddLockdown()369 public void testUpdateUidLockdownRuleAddLockdown() throws Exception { 370 doTestUpdateUidLockdownRule(NO_IIF, NO_MATCH, ADD); 371 372 // Other matches are enabled 373 doTestUpdateUidLockdownRule( 374 NO_IIF, DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH, ADD); 375 376 // IIF_MATCH is enabled 377 doTestUpdateUidLockdownRule(TEST_IF_INDEX, DOZABLE_MATCH, ADD); 378 379 // LOCKDOWN_VPN_MATCH is already enabled 380 doTestUpdateUidLockdownRule(NO_IIF, LOCKDOWN_VPN_MATCH | DOZABLE_MATCH, ADD); 381 } 382 383 @Test 384 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testUpdateUidLockdownRuleRemoveLockdown()385 public void testUpdateUidLockdownRuleRemoveLockdown() throws Exception { 386 doTestUpdateUidLockdownRule(NO_IIF, LOCKDOWN_VPN_MATCH, REMOVE); 387 388 // LOCKDOWN_VPN_MATCH with other matches 389 doTestUpdateUidLockdownRule( 390 NO_IIF, LOCKDOWN_VPN_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH, REMOVE); 391 392 // LOCKDOWN_VPN_MATCH with IIF_MATCH 393 doTestUpdateUidLockdownRule(TEST_IF_INDEX, LOCKDOWN_VPN_MATCH | IIF_MATCH, REMOVE); 394 395 // LOCKDOWN_VPN_MATCH is not enabled 396 doTestUpdateUidLockdownRule(NO_IIF, POWERSAVE_MATCH | RESTRICTED_MATCH, REMOVE); 397 } 398 399 @Test 400 @IgnoreAfter(Build.VERSION_CODES.S_V2) testUpdateUidLockdownRuleBeforeT()401 public void testUpdateUidLockdownRuleBeforeT() { 402 assertThrows(UnsupportedOperationException.class, 403 () -> mBpfNetMaps.updateUidLockdownRule(TEST_UID, true /* add */)); 404 } 405 406 @Test 407 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testAddUidInterfaceRules()408 public void testAddUidInterfaceRules() throws Exception { 409 final int uid0 = TEST_UIDS[0]; 410 final int uid1 = TEST_UIDS[1]; 411 412 mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS); 413 414 checkUidOwnerValue(uid0, TEST_IF_INDEX, IIF_MATCH); 415 checkUidOwnerValue(uid1, TEST_IF_INDEX, IIF_MATCH); 416 } 417 418 @Test 419 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testAddUidInterfaceRulesWithOtherMatch()420 public void testAddUidInterfaceRulesWithOtherMatch() throws Exception { 421 final int uid0 = TEST_UIDS[0]; 422 final int uid1 = TEST_UIDS[1]; 423 final long match0 = DOZABLE_MATCH; 424 final long match1 = DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH; 425 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(NO_IIF, match0)); 426 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NO_IIF, match1)); 427 428 mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS); 429 430 checkUidOwnerValue(uid0, TEST_IF_INDEX, match0 | IIF_MATCH); 431 checkUidOwnerValue(uid1, TEST_IF_INDEX, match1 | IIF_MATCH); 432 } 433 434 @Test 435 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testAddUidInterfaceRulesWithExistingIifMatch()436 public void testAddUidInterfaceRulesWithExistingIifMatch() throws Exception { 437 final int uid0 = TEST_UIDS[0]; 438 final int uid1 = TEST_UIDS[1]; 439 final long match0 = IIF_MATCH; 440 final long match1 = IIF_MATCH | DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH; 441 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX + 1, match0)); 442 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1)); 443 444 mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS); 445 446 checkUidOwnerValue(uid0, TEST_IF_INDEX, match0); 447 checkUidOwnerValue(uid1, TEST_IF_INDEX, match1); 448 } 449 450 @Test 451 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testAddUidInterfaceRulesGetIfIndexFail()452 public void testAddUidInterfaceRulesGetIfIndexFail() { 453 doReturn(0).when(mDeps).getIfIndex(TEST_IF_NAME); 454 assertThrows(ServiceSpecificException.class, 455 () -> mBpfNetMaps.addUidInterfaceRules(TEST_IF_NAME, TEST_UIDS)); 456 } 457 458 @Test 459 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testAddUidInterfaceRulesWithNullInterface()460 public void testAddUidInterfaceRulesWithNullInterface() throws Exception { 461 final int uid0 = TEST_UIDS[0]; 462 final int uid1 = TEST_UIDS[1]; 463 final long match0 = IIF_MATCH; 464 final long match1 = IIF_MATCH | DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH; 465 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0)); 466 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1)); 467 468 mBpfNetMaps.addUidInterfaceRules(null /* ifName */, TEST_UIDS); 469 470 checkUidOwnerValue(uid0, NULL_IIF, match0); 471 checkUidOwnerValue(uid1, NULL_IIF, match1); 472 } 473 doTestRemoveUidInterfaceRules(final int iif0, final long match0, final int iif1, final long match1)474 private void doTestRemoveUidInterfaceRules(final int iif0, final long match0, 475 final int iif1, final long match1) throws Exception { 476 final int uid0 = TEST_UIDS[0]; 477 final int uid1 = TEST_UIDS[1]; 478 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(iif0, match0)); 479 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(iif1, match1)); 480 481 mBpfNetMaps.removeUidInterfaceRules(TEST_UIDS); 482 483 checkUidOwnerValue(uid0, NO_IIF, match0 & ~IIF_MATCH); 484 checkUidOwnerValue(uid1, NO_IIF, match1 & ~IIF_MATCH); 485 } 486 487 @Test 488 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testRemoveUidInterfaceRules()489 public void testRemoveUidInterfaceRules() throws Exception { 490 doTestRemoveUidInterfaceRules(TEST_IF_INDEX, IIF_MATCH, NULL_IIF, IIF_MATCH); 491 492 // IIF_MATCH and other matches are enabled 493 doTestRemoveUidInterfaceRules(TEST_IF_INDEX, IIF_MATCH | DOZABLE_MATCH, 494 NULL_IIF, IIF_MATCH | DOZABLE_MATCH | RESTRICTED_MATCH); 495 496 // IIF_MATCH is not enabled 497 doTestRemoveUidInterfaceRules(NO_IIF, DOZABLE_MATCH, 498 NO_IIF, DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH); 499 } 500 doTestSetUidRule(final List<Integer> testChains)501 private void doTestSetUidRule(final List<Integer> testChains) throws Exception { 502 mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(TEST_IF_INDEX, IIF_MATCH)); 503 504 for (final int chain: testChains) { 505 final int ruleToAddMatch = BpfNetMapsUtils.isFirewallAllowList(chain) 506 ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DENY; 507 mBpfNetMaps.setUidRule(chain, TEST_UID, ruleToAddMatch); 508 } 509 510 checkUidOwnerValue(TEST_UID, TEST_IF_INDEX, IIF_MATCH | getMatch(testChains)); 511 512 for (final int chain: testChains) { 513 final int ruleToRemoveMatch = BpfNetMapsUtils.isFirewallAllowList(chain) 514 ? FIREWALL_RULE_DENY : FIREWALL_RULE_ALLOW; 515 mBpfNetMaps.setUidRule(chain, TEST_UID, ruleToRemoveMatch); 516 } 517 518 checkUidOwnerValue(TEST_UID, TEST_IF_INDEX, IIF_MATCH); 519 } 520 doTestSetUidRule(final int testChain)521 private void doTestSetUidRule(final int testChain) throws Exception { 522 doTestSetUidRule(List.of(testChain)); 523 } 524 525 @Test 526 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetUidRule()527 public void testSetUidRule() throws Exception { 528 doTestSetUidRule(FIREWALL_CHAIN_DOZABLE); 529 doTestSetUidRule(FIREWALL_CHAIN_STANDBY); 530 doTestSetUidRule(FIREWALL_CHAIN_POWERSAVE); 531 doTestSetUidRule(FIREWALL_CHAIN_RESTRICTED); 532 doTestSetUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY); 533 doTestSetUidRule(FIREWALL_CHAIN_OEM_DENY_1); 534 doTestSetUidRule(FIREWALL_CHAIN_OEM_DENY_2); 535 doTestSetUidRule(FIREWALL_CHAIN_OEM_DENY_3); 536 doTestSetUidRule(FIREWALL_CHAIN_METERED_ALLOW); 537 doTestSetUidRule(FIREWALL_CHAIN_METERED_DENY_USER); 538 doTestSetUidRule(FIREWALL_CHAIN_METERED_DENY_ADMIN); 539 } 540 541 @Test 542 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetUidRuleMultipleChain()543 public void testSetUidRuleMultipleChain() throws Exception { 544 doTestSetUidRule(List.of( 545 FIREWALL_CHAIN_DOZABLE, 546 FIREWALL_CHAIN_STANDBY)); 547 doTestSetUidRule(List.of( 548 FIREWALL_CHAIN_DOZABLE, 549 FIREWALL_CHAIN_STANDBY, 550 FIREWALL_CHAIN_POWERSAVE, 551 FIREWALL_CHAIN_RESTRICTED)); 552 doTestSetUidRule(FIREWALL_CHAINS); 553 } 554 555 @Test 556 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetUidRuleRemoveRuleFromUidWithNoRule()557 public void testSetUidRuleRemoveRuleFromUidWithNoRule() { 558 final Class<ServiceSpecificException> expected = ServiceSpecificException.class; 559 assertThrows(expected, 560 () -> mBpfNetMaps.setUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID, FIREWALL_RULE_DENY)); 561 } 562 563 @Test 564 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetUidRuleInvalidChain()565 public void testSetUidRuleInvalidChain() { 566 final Class<ServiceSpecificException> expected = ServiceSpecificException.class; 567 assertThrows(expected, 568 () -> mBpfNetMaps.setUidRule(-1 /* childChain */, TEST_UID, FIREWALL_RULE_ALLOW)); 569 assertThrows(expected, 570 () -> mBpfNetMaps.setUidRule(1000 /* childChain */, TEST_UID, FIREWALL_RULE_ALLOW)); 571 } 572 573 @Test 574 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetUidRuleInvalidRule()575 public void testSetUidRuleInvalidRule() { 576 final Class<ServiceSpecificException> expected = ServiceSpecificException.class; 577 assertThrows(expected, () -> 578 mBpfNetMaps.setUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID, -1 /* firewallRule */)); 579 assertThrows(expected, () -> 580 mBpfNetMaps.setUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID, 1000 /* firewallRule */)); 581 } 582 583 @Test 584 @IgnoreAfter(Build.VERSION_CODES.S_V2) testSetUidRuleBeforeT()585 public void testSetUidRuleBeforeT() { 586 assertThrows(UnsupportedOperationException.class, () -> 587 mBpfNetMaps.setUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID, FIREWALL_RULE_ALLOW)); 588 } 589 doTestGetUidRule(final List<Integer> enableChains)590 private void doTestGetUidRule(final List<Integer> enableChains) throws Exception { 591 mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(0, getMatch(enableChains))); 592 593 for (final int chain: FIREWALL_CHAINS) { 594 final String testCase = "EnabledChains: " + enableChains + " CheckedChain: " + chain; 595 if (enableChains.contains(chain)) { 596 final int expectedRule = BpfNetMapsUtils.isFirewallAllowList(chain) 597 ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DENY; 598 assertEquals(testCase, expectedRule, mBpfNetMaps.getUidRule(chain, TEST_UID)); 599 } else { 600 final int expectedRule = BpfNetMapsUtils.isFirewallAllowList(chain) 601 ? FIREWALL_RULE_DENY : FIREWALL_RULE_ALLOW; 602 assertEquals(testCase, expectedRule, mBpfNetMaps.getUidRule(chain, TEST_UID)); 603 } 604 } 605 } 606 doTestGetUidRule(final int enableChain)607 private void doTestGetUidRule(final int enableChain) throws Exception { 608 doTestGetUidRule(List.of(enableChain)); 609 } 610 611 @Test 612 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testGetUidRule()613 public void testGetUidRule() throws Exception { 614 doTestGetUidRule(FIREWALL_CHAIN_DOZABLE); 615 doTestGetUidRule(FIREWALL_CHAIN_STANDBY); 616 doTestGetUidRule(FIREWALL_CHAIN_POWERSAVE); 617 doTestGetUidRule(FIREWALL_CHAIN_RESTRICTED); 618 doTestGetUidRule(FIREWALL_CHAIN_LOW_POWER_STANDBY); 619 doTestGetUidRule(FIREWALL_CHAIN_OEM_DENY_1); 620 doTestGetUidRule(FIREWALL_CHAIN_OEM_DENY_2); 621 doTestGetUidRule(FIREWALL_CHAIN_OEM_DENY_3); 622 } 623 624 @Test 625 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testGetUidRuleMultipleChainEnabled()626 public void testGetUidRuleMultipleChainEnabled() throws Exception { 627 doTestGetUidRule(List.of( 628 FIREWALL_CHAIN_DOZABLE, 629 FIREWALL_CHAIN_STANDBY)); 630 doTestGetUidRule(List.of( 631 FIREWALL_CHAIN_DOZABLE, 632 FIREWALL_CHAIN_STANDBY, 633 FIREWALL_CHAIN_POWERSAVE, 634 FIREWALL_CHAIN_RESTRICTED)); 635 doTestGetUidRule(FIREWALL_CHAINS); 636 } 637 638 @Test 639 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testGetUidRuleNoEntry()640 public void testGetUidRuleNoEntry() throws Exception { 641 mUidOwnerMap.clear(); 642 for (final int chain: FIREWALL_CHAINS) { 643 final int expectedRule = BpfNetMapsUtils.isFirewallAllowList(chain) 644 ? FIREWALL_RULE_DENY : FIREWALL_RULE_ALLOW; 645 assertEquals(expectedRule, mBpfNetMaps.getUidRule(chain, TEST_UID)); 646 } 647 } 648 649 @Test 650 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testGetUidRuleInvalidChain()651 public void testGetUidRuleInvalidChain() { 652 final Class<ServiceSpecificException> expected = ServiceSpecificException.class; 653 assertThrows(expected, () -> mBpfNetMaps.getUidRule(-1 /* childChain */, TEST_UID)); 654 assertThrows(expected, () -> mBpfNetMaps.getUidRule(1000 /* childChain */, TEST_UID)); 655 } 656 657 @Test 658 @IgnoreAfter(Build.VERSION_CODES.S_V2) testGetUidRuleBeforeT()659 public void testGetUidRuleBeforeT() { 660 assertThrows(UnsupportedOperationException.class, 661 () -> mBpfNetMaps.getUidRule(FIREWALL_CHAIN_DOZABLE, TEST_UID)); 662 } 663 664 @Test 665 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testReplaceUidChain()666 public void testReplaceUidChain() throws Exception { 667 final int uid0 = TEST_UIDS[0]; 668 final int uid1 = TEST_UIDS[1]; 669 670 mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, TEST_UIDS); 671 672 checkUidOwnerValue(uid0, NO_IIF, DOZABLE_MATCH); 673 checkUidOwnerValue(uid1, NO_IIF, DOZABLE_MATCH); 674 } 675 676 @Test 677 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testReplaceUidChainWithOtherMatch()678 public void testReplaceUidChainWithOtherMatch() throws Exception { 679 final int uid0 = TEST_UIDS[0]; 680 final int uid1 = TEST_UIDS[1]; 681 final long match0 = POWERSAVE_MATCH; 682 final long match1 = POWERSAVE_MATCH | RESTRICTED_MATCH; 683 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(NO_IIF, match0)); 684 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NO_IIF, match1)); 685 686 mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, new int[]{uid1}); 687 688 checkUidOwnerValue(uid0, NO_IIF, match0); 689 checkUidOwnerValue(uid1, NO_IIF, match1 | DOZABLE_MATCH); 690 } 691 692 @Test 693 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testReplaceUidChainWithExistingIifMatch()694 public void testReplaceUidChainWithExistingIifMatch() throws Exception { 695 final int uid0 = TEST_UIDS[0]; 696 final int uid1 = TEST_UIDS[1]; 697 final long match0 = IIF_MATCH; 698 final long match1 = IIF_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH; 699 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0)); 700 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1)); 701 702 mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, TEST_UIDS); 703 704 checkUidOwnerValue(uid0, TEST_IF_INDEX, match0 | DOZABLE_MATCH); 705 checkUidOwnerValue(uid1, NULL_IIF, match1 | DOZABLE_MATCH); 706 } 707 708 @Test 709 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testReplaceUidChainRemoveExistingMatch()710 public void testReplaceUidChainRemoveExistingMatch() throws Exception { 711 final int uid0 = TEST_UIDS[0]; 712 final int uid1 = TEST_UIDS[1]; 713 final long match0 = IIF_MATCH | DOZABLE_MATCH; 714 final long match1 = IIF_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH; 715 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(TEST_IF_INDEX, match0)); 716 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1)); 717 718 mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, new int[]{uid1}); 719 720 checkUidOwnerValue(uid0, TEST_IF_INDEX, match0 & ~DOZABLE_MATCH); 721 checkUidOwnerValue(uid1, NULL_IIF, match1 | DOZABLE_MATCH); 722 } 723 724 @Test 725 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testReplaceUidChainInvalidChain()726 public void testReplaceUidChainInvalidChain() { 727 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 728 assertThrows(expected, () -> mBpfNetMaps.replaceUidChain(-1 /* chain */, TEST_UIDS)); 729 assertThrows(expected, () -> mBpfNetMaps.replaceUidChain(1000 /* chain */, TEST_UIDS)); 730 } 731 732 @Test 733 @IgnoreAfter(Build.VERSION_CODES.S_V2) testReplaceUidChainBeforeT()734 public void testReplaceUidChainBeforeT() { 735 assertThrows(UnsupportedOperationException.class, 736 () -> mBpfNetMaps.replaceUidChain(FIREWALL_CHAIN_DOZABLE, TEST_UIDS)); 737 } 738 739 @Test 740 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsGrantInternetPermission()741 public void testSetNetPermForUidsGrantInternetPermission() throws Exception { 742 mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS); 743 744 assertTrue(mUidPermissionMap.isEmpty()); 745 } 746 747 @Test 748 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsGrantUpdateStatsPermission()749 public void testSetNetPermForUidsGrantUpdateStatsPermission() throws Exception { 750 mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, TEST_UIDS); 751 752 final int uid0 = TEST_UIDS[0]; 753 final int uid1 = TEST_UIDS[1]; 754 assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new S32(uid0)).val); 755 assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new S32(uid1)).val); 756 } 757 758 @Test 759 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsGrantMultiplePermissions()760 public void testSetNetPermForUidsGrantMultiplePermissions() throws Exception { 761 final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS; 762 mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS); 763 764 final int uid0 = TEST_UIDS[0]; 765 final int uid1 = TEST_UIDS[1]; 766 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid0)).val); 767 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val); 768 } 769 770 @Test 771 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsRevokeInternetPermission()772 public void testSetNetPermForUidsRevokeInternetPermission() throws Exception { 773 final int uid0 = TEST_UIDS[0]; 774 final int uid1 = TEST_UIDS[1]; 775 mBpfNetMaps.setNetPermForUids(PERMISSION_INTERNET, TEST_UIDS); 776 mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0}); 777 778 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val); 779 assertNull(mUidPermissionMap.getValue(new S32(uid1))); 780 } 781 782 @Test 783 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsRevokeUpdateDeviceStatsPermission()784 public void testSetNetPermForUidsRevokeUpdateDeviceStatsPermission() throws Exception { 785 final int uid0 = TEST_UIDS[0]; 786 final int uid1 = TEST_UIDS[1]; 787 mBpfNetMaps.setNetPermForUids(PERMISSION_UPDATE_DEVICE_STATS, TEST_UIDS); 788 mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0}); 789 790 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val); 791 assertEquals(PERMISSION_UPDATE_DEVICE_STATS, mUidPermissionMap.getValue(new S32(uid1)).val); 792 } 793 794 @Test 795 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsRevokeMultiplePermissions()796 public void testSetNetPermForUidsRevokeMultiplePermissions() throws Exception { 797 final int uid0 = TEST_UIDS[0]; 798 final int uid1 = TEST_UIDS[1]; 799 final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS; 800 mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS); 801 mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, new int[]{uid0}); 802 803 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val); 804 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val); 805 } 806 807 @Test 808 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsPermissionUninstalled()809 public void testSetNetPermForUidsPermissionUninstalled() throws Exception { 810 final int uid0 = TEST_UIDS[0]; 811 final int uid1 = TEST_UIDS[1]; 812 final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS; 813 mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS); 814 mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, new int[]{uid0}); 815 816 assertNull(mUidPermissionMap.getValue(new S32(uid0))); 817 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val); 818 } 819 820 @Test 821 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetNetPermForUidsDuplicatedRequestSilentlyIgnored()822 public void testSetNetPermForUidsDuplicatedRequestSilentlyIgnored() throws Exception { 823 final int uid0 = TEST_UIDS[0]; 824 final int uid1 = TEST_UIDS[1]; 825 final int permission = PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS; 826 827 mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS); 828 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid0)).val); 829 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val); 830 831 mBpfNetMaps.setNetPermForUids(permission, TEST_UIDS); 832 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid0)).val); 833 assertEquals(permission, mUidPermissionMap.getValue(new S32(uid1)).val); 834 835 mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, TEST_UIDS); 836 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val); 837 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid1)).val); 838 839 mBpfNetMaps.setNetPermForUids(PERMISSION_NONE, TEST_UIDS); 840 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid0)).val); 841 assertEquals(PERMISSION_NONE, mUidPermissionMap.getValue(new S32(uid1)).val); 842 843 mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, TEST_UIDS); 844 assertNull(mUidPermissionMap.getValue(new S32(uid0))); 845 assertNull(mUidPermissionMap.getValue(new S32(uid1))); 846 847 mBpfNetMaps.setNetPermForUids(PERMISSION_UNINSTALLED, TEST_UIDS); 848 assertNull(mUidPermissionMap.getValue(new S32(uid0))); 849 assertNull(mUidPermissionMap.getValue(new S32(uid1))); 850 } 851 852 @Test 853 @IgnoreUpTo(Build.VERSION_CODES.TIRAMISU) testGetNetPermFoUid()854 public void testGetNetPermFoUid() throws Exception { 855 mUidPermissionMap.deleteEntry(new S32(TEST_UID)); 856 assertEquals(PERMISSION_INTERNET, mBpfNetMaps.getNetPermForUid(TEST_UID)); 857 858 mUidPermissionMap.updateEntry(new S32(TEST_UID), new U8((short) PERMISSION_NONE)); 859 assertEquals(PERMISSION_NONE, mBpfNetMaps.getNetPermForUid(TEST_UID)); 860 861 mUidPermissionMap.updateEntry(new S32(TEST_UID), 862 new U8((short) (PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS))); 863 assertEquals(PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS, 864 mBpfNetMaps.getNetPermForUid(TEST_UID)); 865 } 866 867 @Test 868 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSwapActiveStatsMap()869 public void testSwapActiveStatsMap() throws Exception { 870 mConfigurationMap.updateEntry( 871 CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_A)); 872 873 mBpfNetMaps.swapActiveStatsMap(); 874 assertEquals(STATS_SELECT_MAP_B, 875 mConfigurationMap.getValue(CURRENT_STATS_MAP_CONFIGURATION_KEY).val); 876 877 mBpfNetMaps.swapActiveStatsMap(); 878 assertEquals(STATS_SELECT_MAP_A, 879 mConfigurationMap.getValue(CURRENT_STATS_MAP_CONFIGURATION_KEY).val); 880 } 881 882 @Test 883 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSwapActiveStatsMapSynchronizeKernelRCUFail()884 public void testSwapActiveStatsMapSynchronizeKernelRCUFail() throws Exception { 885 doReturn(EPERM).when(mDeps).synchronizeKernelRCU(); 886 mConfigurationMap.updateEntry( 887 CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_A)); 888 889 assertThrows(ServiceSpecificException.class, () -> mBpfNetMaps.swapActiveStatsMap()); 890 } 891 892 @Test 893 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testPullBpfMapInfo()894 public void testPullBpfMapInfo() throws Exception { 895 // mCookieTagMap has 1 entry 896 mCookieTagMap.updateEntry(new CookieTagMapKey(0), new CookieTagMapValue(0, 0)); 897 898 // mUidOwnerMap has 2 entries 899 mUidOwnerMap.updateEntry(new S32(0), new UidOwnerValue(0, 0)); 900 mUidOwnerMap.updateEntry(new S32(1), new UidOwnerValue(0, 0)); 901 902 // mUidPermissionMap has 3 entries 903 mUidPermissionMap.updateEntry(new S32(0), new U8((short) 0)); 904 mUidPermissionMap.updateEntry(new S32(1), new U8((short) 0)); 905 mUidPermissionMap.updateEntry(new S32(2), new U8((short) 0)); 906 907 final int ret = mBpfNetMaps.pullBpfMapInfoAtom(NETWORK_BPF_MAP_INFO, new ArrayList<>()); 908 assertEquals(StatsManager.PULL_SUCCESS, ret); 909 verify(mDeps).buildStatsEvent( 910 1 /* cookieTagMapSize */, 2 /* uidOwnerMapSize */, 3 /* uidPermissionMapSize */); 911 } 912 913 @Test 914 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testPullBpfMapInfoGetMapSizeFailure()915 public void testPullBpfMapInfoGetMapSizeFailure() throws Exception { 916 doThrow(new ErrnoException("", EINVAL)).when(mCookieTagMap).forEach(any()); 917 final int ret = mBpfNetMaps.pullBpfMapInfoAtom(NETWORK_BPF_MAP_INFO, new ArrayList<>()); 918 assertEquals(StatsManager.PULL_SKIP, ret); 919 } 920 921 @Test 922 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testPullBpfMapInfoUnexpectedAtomTag()923 public void testPullBpfMapInfoUnexpectedAtomTag() { 924 final int ret = mBpfNetMaps.pullBpfMapInfoAtom(-1 /* atomTag */, new ArrayList<>()); 925 assertEquals(StatsManager.PULL_SKIP, ret); 926 } 927 assertDumpContains(final String dump, final String message)928 private void assertDumpContains(final String dump, final String message) { 929 assertTrue(String.format("dump(%s) does not contain '%s'", dump, message), 930 dump.contains(message)); 931 } 932 getDump()933 private String getDump() throws Exception { 934 final StringWriter sw = new StringWriter(); 935 mBpfNetMaps.dump(new IndentingPrintWriter(sw), new FileDescriptor(), true /* verbose */); 936 return sw.toString(); 937 } 938 doTestDumpUidPermissionMap(final int permission, final String permissionString)939 private void doTestDumpUidPermissionMap(final int permission, final String permissionString) 940 throws Exception { 941 mUidPermissionMap.updateEntry(new S32(TEST_UID), new U8((short) permission)); 942 assertDumpContains(getDump(), TEST_UID + " " + permissionString); 943 } 944 945 @Test 946 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidPermissionMap()947 public void testDumpUidPermissionMap() throws Exception { 948 doTestDumpUidPermissionMap(PERMISSION_NONE, "PERMISSION_NONE"); 949 doTestDumpUidPermissionMap(PERMISSION_INTERNET | PERMISSION_UPDATE_DEVICE_STATS, 950 "PERMISSION_INTERNET PERMISSION_UPDATE_DEVICE_STATS"); 951 } 952 953 @Test 954 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidPermissionMapInvalidPermission()955 public void testDumpUidPermissionMapInvalidPermission() throws Exception { 956 doTestDumpUidPermissionMap(PERMISSION_UNINSTALLED, "PERMISSION_UNINSTALLED error!"); 957 doTestDumpUidPermissionMap(PERMISSION_INTERNET | 1 << 6, 958 "PERMISSION_INTERNET PERMISSION_UNKNOWN(64)"); 959 } 960 doTestDumpUidOwnerMap(final int iif, final long match, final String matchString)961 void doTestDumpUidOwnerMap(final int iif, final long match, final String matchString) 962 throws Exception { 963 mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(iif, match)); 964 assertDumpContains(getDump(), TEST_UID + " " + matchString); 965 } 966 doTestDumpUidOwnerMap(final long match, final String matchString)967 void doTestDumpUidOwnerMap(final long match, final String matchString) throws Exception { 968 doTestDumpUidOwnerMap(0 /* iif */, match, matchString); 969 } 970 971 @Test 972 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidOwnerMap()973 public void testDumpUidOwnerMap() throws Exception { 974 doTestDumpUidOwnerMap(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"); 975 doTestDumpUidOwnerMap(PENALTY_BOX_USER_MATCH, "PENALTY_BOX_USER_MATCH"); 976 doTestDumpUidOwnerMap(DOZABLE_MATCH, "DOZABLE_MATCH"); 977 doTestDumpUidOwnerMap(STANDBY_MATCH, "STANDBY_MATCH"); 978 doTestDumpUidOwnerMap(POWERSAVE_MATCH, "POWERSAVE_MATCH"); 979 doTestDumpUidOwnerMap(RESTRICTED_MATCH, "RESTRICTED_MATCH"); 980 doTestDumpUidOwnerMap(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH"); 981 doTestDumpUidOwnerMap(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"); 982 doTestDumpUidOwnerMap(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"); 983 doTestDumpUidOwnerMap(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"); 984 doTestDumpUidOwnerMap(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH"); 985 doTestDumpUidOwnerMap(PENALTY_BOX_ADMIN_MATCH, "PENALTY_BOX_ADMIN_MATCH"); 986 987 doTestDumpUidOwnerMap(HAPPY_BOX_MATCH | POWERSAVE_MATCH, 988 "HAPPY_BOX_MATCH POWERSAVE_MATCH"); 989 doTestDumpUidOwnerMap(DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH, 990 "DOZABLE_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH"); 991 } 992 993 @Test 994 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidOwnerMapWithIifMatch()995 public void testDumpUidOwnerMapWithIifMatch() throws Exception { 996 doTestDumpUidOwnerMap(TEST_IF_INDEX, IIF_MATCH, "IIF_MATCH " + TEST_IF_INDEX); 997 doTestDumpUidOwnerMap(TEST_IF_INDEX, 998 IIF_MATCH | DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH, 999 "DOZABLE_MATCH IIF_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH " + TEST_IF_INDEX); 1000 } 1001 1002 @Test 1003 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidOwnerMapWithInvalidMatch()1004 public void testDumpUidOwnerMapWithInvalidMatch() throws Exception { 1005 final long invalid_match = 1L << 31; 1006 doTestDumpUidOwnerMap(invalid_match, "UNKNOWN_MATCH(" + invalid_match + ")"); 1007 doTestDumpUidOwnerMap(DOZABLE_MATCH | invalid_match, 1008 "DOZABLE_MATCH UNKNOWN_MATCH(" + invalid_match + ")"); 1009 } 1010 1011 @Test 1012 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpCurrentStatsMapConfig()1013 public void testDumpCurrentStatsMapConfig() throws Exception { 1014 mConfigurationMap.updateEntry( 1015 CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_A)); 1016 assertDumpContains(getDump(), "current statsMap configuration: 0 SELECT_MAP_A"); 1017 1018 mConfigurationMap.updateEntry( 1019 CURRENT_STATS_MAP_CONFIGURATION_KEY, new U32(STATS_SELECT_MAP_B)); 1020 assertDumpContains(getDump(), "current statsMap configuration: 1 SELECT_MAP_B"); 1021 } 1022 doTestDumpOwnerMatchConfig(final long match, final String matchString)1023 private void doTestDumpOwnerMatchConfig(final long match, final String matchString) 1024 throws Exception { 1025 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(match)); 1026 assertDumpContains(getDump(), 1027 "current ownerMatch configuration: " + match + " " + matchString); 1028 } 1029 1030 @Test 1031 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidOwnerMapConfig()1032 public void testDumpUidOwnerMapConfig() throws Exception { 1033 doTestDumpOwnerMatchConfig(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"); 1034 doTestDumpOwnerMatchConfig(DOZABLE_MATCH, "DOZABLE_MATCH"); 1035 doTestDumpOwnerMatchConfig(STANDBY_MATCH, "STANDBY_MATCH"); 1036 doTestDumpOwnerMatchConfig(POWERSAVE_MATCH, "POWERSAVE_MATCH"); 1037 doTestDumpOwnerMatchConfig(RESTRICTED_MATCH, "RESTRICTED_MATCH"); 1038 doTestDumpOwnerMatchConfig(LOW_POWER_STANDBY_MATCH, "LOW_POWER_STANDBY_MATCH"); 1039 doTestDumpOwnerMatchConfig(IIF_MATCH, "IIF_MATCH"); 1040 doTestDumpOwnerMatchConfig(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"); 1041 doTestDumpOwnerMatchConfig(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"); 1042 doTestDumpOwnerMatchConfig(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"); 1043 doTestDumpOwnerMatchConfig(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH"); 1044 1045 doTestDumpOwnerMatchConfig(HAPPY_BOX_MATCH | POWERSAVE_MATCH, 1046 "HAPPY_BOX_MATCH POWERSAVE_MATCH"); 1047 doTestDumpOwnerMatchConfig(DOZABLE_MATCH | LOCKDOWN_VPN_MATCH | OEM_DENY_1_MATCH, 1048 "DOZABLE_MATCH LOCKDOWN_VPN_MATCH OEM_DENY_1_MATCH"); 1049 } 1050 1051 @Test 1052 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpUidOwnerMapConfigWithInvalidMatch()1053 public void testDumpUidOwnerMapConfigWithInvalidMatch() throws Exception { 1054 final long invalid_match = 1L << 31; 1055 doTestDumpOwnerMatchConfig(invalid_match, "UNKNOWN_MATCH(" + invalid_match + ")"); 1056 doTestDumpOwnerMatchConfig(DOZABLE_MATCH | invalid_match, 1057 "DOZABLE_MATCH UNKNOWN_MATCH(" + invalid_match + ")"); 1058 } 1059 1060 @Test 1061 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpCookieTagMap()1062 public void testDumpCookieTagMap() throws Exception { 1063 mCookieTagMap.updateEntry(new CookieTagMapKey(123), new CookieTagMapValue(456, 0x789)); 1064 assertDumpContains(getDump(), "cookie=123 tag=0x789 uid=456"); 1065 } 1066 doTestDumpDataSaverConfig(final short value, final boolean expected)1067 private void doTestDumpDataSaverConfig(final short value, final boolean expected) 1068 throws Exception { 1069 mDataSaverEnabledMap.updateEntry(DATA_SAVER_ENABLED_KEY, new U8(value)); 1070 assertDumpContains(getDump(), 1071 "sDataSaverEnabledMap: " + expected); 1072 } 1073 1074 @Test 1075 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpDataSaverConfig()1076 public void testDumpDataSaverConfig() throws Exception { 1077 doTestDumpDataSaverConfig(DATA_SAVER_DISABLED, false); 1078 doTestDumpDataSaverConfig(DATA_SAVER_ENABLED, true); 1079 doTestDumpDataSaverConfig((short) 2, true); 1080 } 1081 1082 @Test testGetUids()1083 public void testGetUids() throws ErrnoException { 1084 final int uid0 = TEST_UIDS[0]; 1085 final int uid1 = TEST_UIDS[1]; 1086 final long match0 = DOZABLE_MATCH | POWERSAVE_MATCH; 1087 final long match1 = DOZABLE_MATCH | STANDBY_MATCH; 1088 mUidOwnerMap.updateEntry(new S32(uid0), new UidOwnerValue(NULL_IIF, match0)); 1089 mUidOwnerMap.updateEntry(new S32(uid1), new UidOwnerValue(NULL_IIF, match1)); 1090 1091 assertEquals(new ArraySet<>(List.of(uid0, uid1)), 1092 mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(FIREWALL_CHAIN_DOZABLE)); 1093 assertEquals(new ArraySet<>(List.of(uid0)), 1094 mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(FIREWALL_CHAIN_POWERSAVE)); 1095 1096 assertEquals(new ArraySet<>(List.of(uid1)), 1097 mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(FIREWALL_CHAIN_STANDBY)); 1098 assertEquals(new ArraySet<>(), 1099 mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(FIREWALL_CHAIN_OEM_DENY_1)); 1100 } 1101 1102 @Test testGetUidsIllegalArgument()1103 public void testGetUidsIllegalArgument() { 1104 final Class<IllegalArgumentException> expected = IllegalArgumentException.class; 1105 assertThrows(expected, 1106 () -> mBpfNetMaps.getUidsWithDenyRuleOnDenyListChain(FIREWALL_CHAIN_DOZABLE)); 1107 assertThrows(expected, 1108 () -> mBpfNetMaps.getUidsWithAllowRuleOnAllowListChain(FIREWALL_CHAIN_OEM_DENY_1)); 1109 } 1110 1111 @Test 1112 @IgnoreAfter(Build.VERSION_CODES.S_V2) testSetDataSaverEnabledBeforeT()1113 public void testSetDataSaverEnabledBeforeT() { 1114 for (boolean enable : new boolean[]{true, false}) { 1115 assertThrows(UnsupportedOperationException.class, 1116 () -> mBpfNetMaps.setDataSaverEnabled(enable)); 1117 } 1118 } 1119 1120 @Test 1121 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetDataSaverEnabled()1122 public void testSetDataSaverEnabled() throws Exception { 1123 for (boolean enable : new boolean[]{true, false}) { 1124 mBpfNetMaps.setDataSaverEnabled(enable); 1125 assertEquals(enable ? DATA_SAVER_ENABLED : DATA_SAVER_DISABLED, 1126 mDataSaverEnabledMap.getValue(DATA_SAVER_ENABLED_KEY).val); 1127 } 1128 } 1129 1130 @Test 1131 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetIngressDiscardRule_V4address()1132 public void testSetIngressDiscardRule_V4address() throws Exception { 1133 mBpfNetMaps.setIngressDiscardRule(TEST_V4_ADDRESS, TEST_IF_NAME); 1134 final IngressDiscardValue val = mIngressDiscardMap.getValue(new IngressDiscardKey( 1135 TEST_V4_ADDRESS)); 1136 assertEquals(TEST_IF_INDEX, val.iif1); 1137 assertEquals(TEST_IF_INDEX, val.iif2); 1138 } 1139 1140 @Test 1141 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testSetIngressDiscardRule_V6address()1142 public void testSetIngressDiscardRule_V6address() throws Exception { 1143 mBpfNetMaps.setIngressDiscardRule(TEST_V6_ADDRESS, TEST_IF_NAME); 1144 final IngressDiscardValue val = 1145 mIngressDiscardMap.getValue(new IngressDiscardKey(TEST_V6_ADDRESS)); 1146 assertEquals(TEST_IF_INDEX, val.iif1); 1147 assertEquals(TEST_IF_INDEX, val.iif2); 1148 } 1149 1150 @Test 1151 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testRemoveIngressDiscardRule()1152 public void testRemoveIngressDiscardRule() throws Exception { 1153 mBpfNetMaps.setIngressDiscardRule(TEST_V4_ADDRESS, TEST_IF_NAME); 1154 mBpfNetMaps.setIngressDiscardRule(TEST_V6_ADDRESS, TEST_IF_NAME); 1155 final IngressDiscardKey v4Key = new IngressDiscardKey(TEST_V4_ADDRESS); 1156 final IngressDiscardKey v6Key = new IngressDiscardKey(TEST_V6_ADDRESS); 1157 assertTrue(mIngressDiscardMap.containsKey(v4Key)); 1158 assertTrue(mIngressDiscardMap.containsKey(v6Key)); 1159 1160 mBpfNetMaps.removeIngressDiscardRule(TEST_V4_ADDRESS); 1161 assertFalse(mIngressDiscardMap.containsKey(v4Key)); 1162 assertTrue(mIngressDiscardMap.containsKey(v6Key)); 1163 1164 mBpfNetMaps.removeIngressDiscardRule(TEST_V6_ADDRESS); 1165 assertFalse(mIngressDiscardMap.containsKey(v4Key)); 1166 assertFalse(mIngressDiscardMap.containsKey(v6Key)); 1167 } 1168 1169 @Test 1170 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testDumpIngressDiscardRule()1171 public void testDumpIngressDiscardRule() throws Exception { 1172 mBpfNetMaps.setIngressDiscardRule(TEST_V4_ADDRESS, TEST_IF_NAME); 1173 mBpfNetMaps.setIngressDiscardRule(TEST_V6_ADDRESS, TEST_IF_NAME); 1174 final String dump = getDump(); 1175 assertDumpContains(dump, TEST_V4_ADDRESS.getHostAddress()); 1176 assertDumpContains(dump, TEST_V6_ADDRESS.getHostAddress()); 1177 assertDumpContains(dump, TEST_IF_INDEX + "(" + TEST_IF_NAME + ")"); 1178 } 1179 doTestGetUidNetworkingBlockedReasons( final long configurationMatches, final long uidRules, final short dataSaverStatus, final int expectedBlockedReasons )1180 private void doTestGetUidNetworkingBlockedReasons( 1181 final long configurationMatches, 1182 final long uidRules, 1183 final short dataSaverStatus, 1184 final int expectedBlockedReasons 1185 ) throws Exception { 1186 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(configurationMatches)); 1187 mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(NULL_IIF, uidRules)); 1188 mDataSaverEnabledMap.updateEntry(DATA_SAVER_ENABLED_KEY, new U8(dataSaverStatus)); 1189 1190 assertEquals(expectedBlockedReasons, mBpfNetMaps.getUidNetworkingBlockedReasons(TEST_UID)); 1191 } 1192 1193 @Test 1194 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testGetUidNetworkingBlockedReasons()1195 public void testGetUidNetworkingBlockedReasons() throws Exception { 1196 doTestGetUidNetworkingBlockedReasons( 1197 NO_MATCH, 1198 NO_MATCH, 1199 DATA_SAVER_DISABLED, 1200 BLOCKED_REASON_NONE 1201 ); 1202 doTestGetUidNetworkingBlockedReasons( 1203 DOZABLE_MATCH, 1204 NO_MATCH, 1205 DATA_SAVER_DISABLED, 1206 BLOCKED_REASON_DOZE 1207 ); 1208 doTestGetUidNetworkingBlockedReasons( 1209 DOZABLE_MATCH | POWERSAVE_MATCH | STANDBY_MATCH, 1210 DOZABLE_MATCH | STANDBY_MATCH, 1211 DATA_SAVER_DISABLED, 1212 BLOCKED_REASON_BATTERY_SAVER | BLOCKED_REASON_APP_STANDBY 1213 ); 1214 doTestGetUidNetworkingBlockedReasons( 1215 OEM_DENY_1_MATCH | OEM_DENY_2_MATCH | OEM_DENY_3_MATCH, 1216 OEM_DENY_1_MATCH | OEM_DENY_3_MATCH, 1217 DATA_SAVER_DISABLED, 1218 BLOCKED_REASON_OEM_DENY 1219 ); 1220 doTestGetUidNetworkingBlockedReasons( 1221 DOZABLE_MATCH, 1222 DOZABLE_MATCH | BACKGROUND_MATCH | STANDBY_MATCH, 1223 DATA_SAVER_DISABLED, 1224 BLOCKED_REASON_NONE 1225 ); 1226 1227 // Note that HAPPY_BOX and PENALTY_BOX are not disabled by configuration map 1228 doTestGetUidNetworkingBlockedReasons( 1229 NO_MATCH, 1230 PENALTY_BOX_USER_MATCH, 1231 DATA_SAVER_DISABLED, 1232 BLOCKED_METERED_REASON_USER_RESTRICTED 1233 ); 1234 doTestGetUidNetworkingBlockedReasons( 1235 NO_MATCH, 1236 PENALTY_BOX_ADMIN_MATCH, 1237 DATA_SAVER_ENABLED, 1238 BLOCKED_METERED_REASON_ADMIN_DISABLED | BLOCKED_METERED_REASON_DATA_SAVER 1239 ); 1240 doTestGetUidNetworkingBlockedReasons( 1241 NO_MATCH, 1242 PENALTY_BOX_USER_MATCH | PENALTY_BOX_ADMIN_MATCH | HAPPY_BOX_MATCH, 1243 DATA_SAVER_ENABLED, 1244 BLOCKED_METERED_REASON_USER_RESTRICTED | BLOCKED_METERED_REASON_ADMIN_DISABLED 1245 ); 1246 doTestGetUidNetworkingBlockedReasons( 1247 STANDBY_MATCH, 1248 STANDBY_MATCH | PENALTY_BOX_USER_MATCH | HAPPY_BOX_MATCH, 1249 DATA_SAVER_ENABLED, 1250 BLOCKED_REASON_APP_STANDBY | BLOCKED_METERED_REASON_USER_RESTRICTED 1251 ); 1252 } 1253 1254 @Test 1255 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testIsUidNetworkingBlockedForCoreUids()1256 public void testIsUidNetworkingBlockedForCoreUids() throws Exception { 1257 final long allowlistMatch = BACKGROUND_MATCH; // Enable any allowlist match. 1258 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(allowlistMatch)); 1259 1260 // Verify that a normal uid that is not on this chain is indeed blocked. 1261 assertTrue(BpfNetMapsUtils.isUidNetworkingBlocked(TEST_UID, false, mConfigurationMap, 1262 mUidOwnerMap, mDataSaverEnabledMap)); 1263 1264 final int[] coreAids = new int[] { 1265 Process.ROOT_UID, 1266 Process.SYSTEM_UID, 1267 Process.FIRST_APPLICATION_UID - 10, 1268 Process.FIRST_APPLICATION_UID - 1, 1269 }; 1270 // Core appIds are not on the chain but should still be allowed on any user. 1271 for (int userId = 0; userId < 20; userId++) { 1272 for (final int aid : coreAids) { 1273 final int uid = UserHandle.getUid(userId, aid); 1274 assertFalse(BpfNetMapsUtils.isUidNetworkingBlocked(uid, false, mConfigurationMap, 1275 mUidOwnerMap, mDataSaverEnabledMap)); 1276 } 1277 } 1278 } 1279 doTestIsUidRestrictedOnMeteredNetworks( final long enabledMatches, final long uidRules, final short dataSaver, final boolean expectedRestricted )1280 private void doTestIsUidRestrictedOnMeteredNetworks( 1281 final long enabledMatches, 1282 final long uidRules, 1283 final short dataSaver, 1284 final boolean expectedRestricted 1285 ) throws Exception { 1286 mConfigurationMap.updateEntry(UID_RULES_CONFIGURATION_KEY, new U32(enabledMatches)); 1287 mUidOwnerMap.updateEntry(new S32(TEST_UID), new UidOwnerValue(NULL_IIF, uidRules)); 1288 mDataSaverEnabledMap.updateEntry(DATA_SAVER_ENABLED_KEY, new U8(dataSaver)); 1289 1290 assertEquals(expectedRestricted, mBpfNetMaps.isUidRestrictedOnMeteredNetworks(TEST_UID)); 1291 } 1292 1293 @Test 1294 @IgnoreUpTo(Build.VERSION_CODES.S_V2) testIsUidRestrictedOnMeteredNetworks()1295 public void testIsUidRestrictedOnMeteredNetworks() throws Exception { 1296 doTestIsUidRestrictedOnMeteredNetworks( 1297 NO_MATCH, 1298 NO_MATCH, 1299 DATA_SAVER_DISABLED, 1300 false /* expectRestricted */ 1301 ); 1302 doTestIsUidRestrictedOnMeteredNetworks( 1303 DOZABLE_MATCH | POWERSAVE_MATCH | STANDBY_MATCH, 1304 DOZABLE_MATCH | STANDBY_MATCH , 1305 DATA_SAVER_DISABLED, 1306 false /* expectRestricted */ 1307 ); 1308 doTestIsUidRestrictedOnMeteredNetworks( 1309 NO_MATCH, 1310 PENALTY_BOX_USER_MATCH, 1311 DATA_SAVER_DISABLED, 1312 true /* expectRestricted */ 1313 ); 1314 doTestIsUidRestrictedOnMeteredNetworks( 1315 NO_MATCH, 1316 PENALTY_BOX_ADMIN_MATCH, 1317 DATA_SAVER_DISABLED, 1318 true /* expectRestricted */ 1319 ); 1320 doTestIsUidRestrictedOnMeteredNetworks( 1321 NO_MATCH, 1322 PENALTY_BOX_USER_MATCH | PENALTY_BOX_ADMIN_MATCH | HAPPY_BOX_MATCH, 1323 DATA_SAVER_DISABLED, 1324 true /* expectRestricted */ 1325 ); 1326 doTestIsUidRestrictedOnMeteredNetworks( 1327 NO_MATCH, 1328 NO_MATCH, 1329 DATA_SAVER_ENABLED, 1330 true /* expectRestricted */ 1331 ); 1332 doTestIsUidRestrictedOnMeteredNetworks( 1333 NO_MATCH, 1334 HAPPY_BOX_MATCH, 1335 DATA_SAVER_ENABLED, 1336 false /* expectRestricted */ 1337 ); 1338 } 1339 } 1340