1 /* <lambda>null2 * Copyright (C) 2024 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 android.net.BpfNetMapsConstants.METERED_ALLOW_CHAINS 20 import android.net.BpfNetMapsConstants.METERED_DENY_CHAINS 21 import android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND 22 import android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_ALLOW 23 import android.net.ConnectivityManager.FIREWALL_CHAIN_METERED_DENY_USER 24 import android.net.ConnectivityManager.FIREWALL_RULE_ALLOW 25 import android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT 26 import android.net.ConnectivityManager.FIREWALL_RULE_DENY 27 import android.os.Build 28 import androidx.test.filters.SmallTest 29 import com.android.server.connectivity.ConnectivityFlags.BACKGROUND_FIREWALL_CHAIN 30 import com.android.testutils.DevSdkIgnoreRule 31 import com.android.testutils.DevSdkIgnoreRule.IgnoreAfter 32 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo 33 import com.android.testutils.DevSdkIgnoreRunner 34 import com.android.testutils.assertThrows 35 import org.junit.Rule 36 import org.junit.Test 37 import org.junit.runner.RunWith 38 import org.mockito.ArgumentMatchers.anyBoolean 39 import org.mockito.ArgumentMatchers.anyInt 40 import org.mockito.Mockito.any 41 import org.mockito.Mockito.clearInvocations 42 import org.mockito.Mockito.never 43 import org.mockito.Mockito.verify 44 45 @RunWith(DevSdkIgnoreRunner::class) 46 @SmallTest 47 @IgnoreUpTo(Build.VERSION_CODES.S_V2) 48 class CSFirewallChainTest : CSTest() { 49 @get:Rule 50 val ignoreRule = DevSdkIgnoreRule() 51 52 // Tests for setFirewallChainEnabled on FIREWALL_CHAIN_BACKGROUND 53 @Test 54 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, false)]) 55 fun setFirewallChainEnabled_backgroundChainDisabled() { 56 verifySetFirewallChainEnabledOnBackgroundDoesNothing() 57 } 58 59 @Test 60 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)]) 61 @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 62 fun setFirewallChainEnabled_backgroundChainEnabled_afterU() { 63 cm.setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true) 64 verify(bpfNetMaps).setChildChain(FIREWALL_CHAIN_BACKGROUND, true) 65 66 clearInvocations(bpfNetMaps) 67 68 cm.setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, false) 69 verify(bpfNetMaps).setChildChain(FIREWALL_CHAIN_BACKGROUND, false) 70 } 71 72 @Test 73 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)]) 74 @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 75 fun setFirewallChainEnabled_backgroundChainEnabled_uptoU() { 76 verifySetFirewallChainEnabledOnBackgroundDoesNothing() 77 } 78 79 private fun verifySetFirewallChainEnabledOnBackgroundDoesNothing() { 80 cm.setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, true) 81 verify(bpfNetMaps, never()).setChildChain(anyInt(), anyBoolean()) 82 83 cm.setFirewallChainEnabled(FIREWALL_CHAIN_BACKGROUND, false) 84 verify(bpfNetMaps, never()).setChildChain(anyInt(), anyBoolean()) 85 } 86 87 // Tests for replaceFirewallChain on FIREWALL_CHAIN_BACKGROUND 88 @Test 89 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, false)]) 90 fun replaceFirewallChain_backgroundChainDisabled() { 91 verifyReplaceFirewallChainOnBackgroundDoesNothing() 92 } 93 94 @Test 95 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)]) 96 @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 97 fun replaceFirewallChain_backgroundChainEnabled_afterU() { 98 val uids = intArrayOf(53, 42, 79) 99 cm.replaceFirewallChain(FIREWALL_CHAIN_BACKGROUND, uids) 100 verify(bpfNetMaps).replaceUidChain(FIREWALL_CHAIN_BACKGROUND, uids) 101 } 102 103 @Test 104 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)]) 105 @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 106 fun replaceFirewallChain_backgroundChainEnabled_uptoU() { 107 verifyReplaceFirewallChainOnBackgroundDoesNothing() 108 } 109 110 private fun verifyReplaceFirewallChainOnBackgroundDoesNothing() { 111 val uids = intArrayOf(53, 42, 79) 112 cm.replaceFirewallChain(FIREWALL_CHAIN_BACKGROUND, uids) 113 verify(bpfNetMaps, never()).replaceUidChain(anyInt(), any(IntArray::class.java)) 114 } 115 116 // Tests for setUidFirewallRule on FIREWALL_CHAIN_BACKGROUND 117 @Test 118 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, false)]) 119 fun setUidFirewallRule_backgroundChainDisabled() { 120 verifySetUidFirewallRuleOnBackgroundDoesNothing() 121 } 122 123 @Test 124 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)]) 125 @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 126 fun setUidFirewallRule_backgroundChainEnabled_afterU() { 127 val uid = 2345 128 129 cm.setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_DEFAULT) 130 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_DENY) 131 132 clearInvocations(bpfNetMaps) 133 134 cm.setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_DENY) 135 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_DENY) 136 137 clearInvocations(bpfNetMaps) 138 139 cm.setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_ALLOW) 140 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_BACKGROUND, uid, FIREWALL_RULE_ALLOW) 141 } 142 143 @Test 144 @FeatureFlags(flags = [Flag(BACKGROUND_FIREWALL_CHAIN, true)]) 145 @IgnoreAfter(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 146 fun setUidFirewallRule_backgroundChainEnabled_uptoU() { 147 verifySetUidFirewallRuleOnBackgroundDoesNothing() 148 } 149 150 private fun verifySetUidFirewallRuleOnBackgroundDoesNothing() { 151 val uid = 2345 152 153 listOf(FIREWALL_RULE_DEFAULT, FIREWALL_RULE_ALLOW, FIREWALL_RULE_DENY).forEach { rule -> 154 cm.setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, rule) 155 verify(bpfNetMaps, never()).setUidRule(anyInt(), anyInt(), anyInt()) 156 } 157 } 158 159 @Test 160 fun testSetFirewallChainEnabled_meteredChain() { 161 (METERED_ALLOW_CHAINS + METERED_DENY_CHAINS).forEach { 162 assertThrows(UnsupportedOperationException::class.java) { 163 cm.setFirewallChainEnabled(it, true) 164 } 165 assertThrows(UnsupportedOperationException::class.java) { 166 cm.setFirewallChainEnabled(it, false) 167 } 168 } 169 } 170 171 @Test 172 fun testAddUidToMeteredNetworkAllowList() { 173 val uid = 1001 174 cm.addUidToMeteredNetworkAllowList(uid) 175 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_ALLOW) 176 } 177 178 @Test 179 fun testRemoveUidFromMeteredNetworkAllowList() { 180 val uid = 1001 181 cm.removeUidFromMeteredNetworkAllowList(uid) 182 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_METERED_ALLOW, uid, FIREWALL_RULE_DENY) 183 } 184 185 @Test 186 fun testAddUidToMeteredNetworkDenyList() { 187 val uid = 1001 188 cm.addUidToMeteredNetworkDenyList(uid) 189 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_DENY) 190 } 191 192 @Test 193 fun testRemoveUidFromMeteredNetworkDenyList() { 194 val uid = 1001 195 cm.removeUidFromMeteredNetworkDenyList(uid) 196 verify(bpfNetMaps).setUidRule(FIREWALL_CHAIN_METERED_DENY_USER, uid, FIREWALL_RULE_ALLOW) 197 } 198 } 199