1 /* 2 * Copyright 2016 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 * FirewallControllerTest.cpp - unit tests for FirewallController.cpp 17 */ 18 19 #include <string> 20 #include <vector> 21 #include <stdio.h> 22 23 #include <gtest/gtest.h> 24 25 #include <android-base/strings.h> 26 #include <android-base/stringprintf.h> 27 28 #include "FirewallController.h" 29 #include "IptablesBaseTest.h" 30 31 using android::base::Join; 32 using android::base::StringPrintf; 33 34 class FirewallControllerTest : public IptablesBaseTest { 35 protected: 36 FirewallControllerTest() { 37 FirewallController::execIptablesRestore = fakeExecIptablesRestore; 38 mFw.mUseBpfOwnerMatch = false; 39 } 40 FirewallController mFw; 41 42 std::string makeUidRules(IptablesTarget a, const char* b, bool c, 43 const std::vector<int32_t>& d) { 44 return mFw.makeUidRules(a, b, c, d); 45 } 46 47 int createChain(const char* a, FirewallType b) { 48 return mFw.createChain(a, b); 49 } 50 }; 51 52 53 TEST_F(FirewallControllerTest, TestCreateWhitelistChain) { 54 std::vector<std::string> expectedRestore4 = { 55 "*filter", 56 ":fw_whitelist -", 57 "-A fw_whitelist -m owner --uid-owner 0-9999 -j RETURN", 58 "-A fw_whitelist -m owner ! --uid-owner 0-4294967294 -j RETURN", 59 "-A fw_whitelist -p esp -j RETURN", 60 "-A fw_whitelist -i lo -j RETURN", 61 "-A fw_whitelist -o lo -j RETURN", 62 "-A fw_whitelist -p tcp --tcp-flags RST RST -j RETURN", 63 "-A fw_whitelist -j DROP", 64 "COMMIT\n" 65 }; 66 std::vector<std::string> expectedRestore6 = { 67 "*filter", 68 ":fw_whitelist -", 69 "-A fw_whitelist -m owner --uid-owner 0-9999 -j RETURN", 70 "-A fw_whitelist -m owner ! --uid-owner 0-4294967294 -j RETURN", 71 "-A fw_whitelist -p esp -j RETURN", 72 "-A fw_whitelist -i lo -j RETURN", 73 "-A fw_whitelist -o lo -j RETURN", 74 "-A fw_whitelist -p tcp --tcp-flags RST RST -j RETURN", 75 "-A fw_whitelist -p icmpv6 --icmpv6-type packet-too-big -j RETURN", 76 "-A fw_whitelist -p icmpv6 --icmpv6-type router-solicitation -j RETURN", 77 "-A fw_whitelist -p icmpv6 --icmpv6-type router-advertisement -j RETURN", 78 "-A fw_whitelist -p icmpv6 --icmpv6-type neighbour-solicitation -j RETURN", 79 "-A fw_whitelist -p icmpv6 --icmpv6-type neighbour-advertisement -j RETURN", 80 "-A fw_whitelist -p icmpv6 --icmpv6-type redirect -j RETURN", 81 "-A fw_whitelist -j DROP", 82 "COMMIT\n" 83 }; 84 std::vector<std::pair<IptablesTarget, std::string>> expectedRestoreCommands = { 85 { V4, android::base::Join(expectedRestore4, '\n') }, 86 { V6, android::base::Join(expectedRestore6, '\n') }, 87 }; 88 89 createChain("fw_whitelist", WHITELIST); 90 expectIptablesRestoreCommands(expectedRestoreCommands); 91 } 92 93 TEST_F(FirewallControllerTest, TestCreateBlacklistChain) { 94 std::vector<std::string> expectedRestore = { 95 "*filter", 96 ":fw_blacklist -", 97 "-A fw_blacklist -i lo -j RETURN", 98 "-A fw_blacklist -o lo -j RETURN", 99 "-A fw_blacklist -p tcp --tcp-flags RST RST -j RETURN", 100 "COMMIT\n" 101 }; 102 std::vector<std::pair<IptablesTarget, std::string>> expectedRestoreCommands = { 103 { V4, android::base::Join(expectedRestore, '\n') }, 104 { V6, android::base::Join(expectedRestore, '\n') }, 105 }; 106 107 createChain("fw_blacklist", BLACKLIST); 108 expectIptablesRestoreCommands(expectedRestoreCommands); 109 } 110 111 TEST_F(FirewallControllerTest, TestSetStandbyRule) { 112 ExpectedIptablesCommands expected = { 113 { V4V6, "*filter\n-D fw_standby -m owner --uid-owner 12345 -j DROP\nCOMMIT\n" } 114 }; 115 mFw.setUidRule(STANDBY, 12345, ALLOW); 116 expectIptablesRestoreCommands(expected); 117 118 expected = { 119 { V4V6, "*filter\n-A fw_standby -m owner --uid-owner 12345 -j DROP\nCOMMIT\n" } 120 }; 121 mFw.setUidRule(STANDBY, 12345, DENY); 122 expectIptablesRestoreCommands(expected); 123 } 124 125 TEST_F(FirewallControllerTest, TestSetDozeRule) { 126 ExpectedIptablesCommands expected = { 127 { V4V6, "*filter\n-I fw_dozable -m owner --uid-owner 54321 -j RETURN\nCOMMIT\n" } 128 }; 129 mFw.setUidRule(DOZABLE, 54321, ALLOW); 130 expectIptablesRestoreCommands(expected); 131 132 expected = { 133 { V4V6, "*filter\n-D fw_dozable -m owner --uid-owner 54321 -j RETURN\nCOMMIT\n" } 134 }; 135 mFw.setUidRule(DOZABLE, 54321, DENY); 136 expectIptablesRestoreCommands(expected); 137 } 138 139 TEST_F(FirewallControllerTest, TestSetFirewallRule) { 140 ExpectedIptablesCommands expected = { 141 { V4V6, "*filter\n" 142 "-A fw_INPUT -m owner --uid-owner 54321 -j DROP\n" 143 "-A fw_OUTPUT -m owner --uid-owner 54321 -j DROP\n" 144 "COMMIT\n" } 145 }; 146 mFw.setUidRule(NONE, 54321, DENY); 147 expectIptablesRestoreCommands(expected); 148 149 expected = { 150 { V4V6, "*filter\n" 151 "-D fw_INPUT -m owner --uid-owner 54321 -j DROP\n" 152 "-D fw_OUTPUT -m owner --uid-owner 54321 -j DROP\n" 153 "COMMIT\n" } 154 }; 155 mFw.setUidRule(NONE, 54321, ALLOW); 156 expectIptablesRestoreCommands(expected); 157 } 158 159 TEST_F(FirewallControllerTest, TestReplaceWhitelistUidRule) { 160 std::string expected = 161 "*filter\n" 162 ":FW_whitechain -\n" 163 "-A FW_whitechain -m owner --uid-owner 10023 -j RETURN\n" 164 "-A FW_whitechain -m owner --uid-owner 10059 -j RETURN\n" 165 "-A FW_whitechain -m owner --uid-owner 10124 -j RETURN\n" 166 "-A FW_whitechain -m owner --uid-owner 10111 -j RETURN\n" 167 "-A FW_whitechain -m owner --uid-owner 110122 -j RETURN\n" 168 "-A FW_whitechain -m owner --uid-owner 210153 -j RETURN\n" 169 "-A FW_whitechain -m owner --uid-owner 210024 -j RETURN\n" 170 "-A FW_whitechain -m owner --uid-owner 0-9999 -j RETURN\n" 171 "-A FW_whitechain -m owner ! --uid-owner 0-4294967294 -j RETURN\n" 172 "-A FW_whitechain -p esp -j RETURN\n" 173 "-A FW_whitechain -i lo -j RETURN\n" 174 "-A FW_whitechain -o lo -j RETURN\n" 175 "-A FW_whitechain -p tcp --tcp-flags RST RST -j RETURN\n" 176 "-A FW_whitechain -p icmpv6 --icmpv6-type packet-too-big -j RETURN\n" 177 "-A FW_whitechain -p icmpv6 --icmpv6-type router-solicitation -j RETURN\n" 178 "-A FW_whitechain -p icmpv6 --icmpv6-type router-advertisement -j RETURN\n" 179 "-A FW_whitechain -p icmpv6 --icmpv6-type neighbour-solicitation -j RETURN\n" 180 "-A FW_whitechain -p icmpv6 --icmpv6-type neighbour-advertisement -j RETURN\n" 181 "-A FW_whitechain -p icmpv6 --icmpv6-type redirect -j RETURN\n" 182 "-A FW_whitechain -j DROP\n" 183 "COMMIT\n"; 184 185 std::vector<int32_t> uids = { 10023, 10059, 10124, 10111, 110122, 210153, 210024 }; 186 EXPECT_EQ(expected, makeUidRules(V6, "FW_whitechain", true, uids)); 187 } 188 189 TEST_F(FirewallControllerTest, TestReplaceBlacklistUidRule) { 190 std::string expected = 191 "*filter\n" 192 ":FW_blackchain -\n" 193 "-A FW_blackchain -i lo -j RETURN\n" 194 "-A FW_blackchain -o lo -j RETURN\n" 195 "-A FW_blackchain -p tcp --tcp-flags RST RST -j RETURN\n" 196 "-A FW_blackchain -m owner --uid-owner 10023 -j DROP\n" 197 "-A FW_blackchain -m owner --uid-owner 10059 -j DROP\n" 198 "-A FW_blackchain -m owner --uid-owner 10124 -j DROP\n" 199 "COMMIT\n"; 200 201 std::vector<int32_t> uids = { 10023, 10059, 10124 }; 202 EXPECT_EQ(expected, makeUidRules(V4 ,"FW_blackchain", false, uids)); 203 } 204 205 TEST_F(FirewallControllerTest, TestEnableChildChains) { 206 std::vector<std::string> expected = { 207 "*filter\n" 208 "-A fw_INPUT -j fw_dozable\n" 209 "-A fw_OUTPUT -j fw_dozable\n" 210 "COMMIT\n" 211 }; 212 EXPECT_EQ(0, mFw.enableChildChains(DOZABLE, true)); 213 expectIptablesRestoreCommands(expected); 214 215 expected = { 216 "*filter\n" 217 "-D fw_INPUT -j fw_powersave\n" 218 "-D fw_OUTPUT -j fw_powersave\n" 219 "COMMIT\n" 220 }; 221 EXPECT_EQ(0, mFw.enableChildChains(POWERSAVE, false)); 222 expectIptablesRestoreCommands(expected); 223 } 224 225 TEST_F(FirewallControllerTest, TestFirewall) { 226 std::vector<std::string> enableCommands = { 227 "*filter\n" 228 "-A fw_INPUT -j DROP\n" 229 "-A fw_OUTPUT -j REJECT\n" 230 "-A fw_FORWARD -j REJECT\n" 231 "COMMIT\n" 232 }; 233 std::vector<std::string> disableCommands = { 234 "*filter\n" 235 ":fw_INPUT -\n" 236 ":fw_OUTPUT -\n" 237 ":fw_FORWARD -\n" 238 "COMMIT\n" 239 }; 240 std::vector<std::string> noCommands = {}; 241 242 EXPECT_EQ(0, mFw.disableFirewall()); 243 expectIptablesRestoreCommands(disableCommands); 244 245 EXPECT_EQ(0, mFw.disableFirewall()); 246 expectIptablesRestoreCommands(disableCommands); 247 248 EXPECT_EQ(0, mFw.enableFirewall(BLACKLIST)); 249 expectIptablesRestoreCommands(disableCommands); 250 251 EXPECT_EQ(0, mFw.enableFirewall(BLACKLIST)); 252 expectIptablesRestoreCommands(noCommands); 253 254 std::vector<std::string> disableEnableCommands; 255 disableEnableCommands.insert( 256 disableEnableCommands.end(), disableCommands.begin(), disableCommands.end()); 257 disableEnableCommands.insert( 258 disableEnableCommands.end(), enableCommands.begin(), enableCommands.end()); 259 260 EXPECT_EQ(0, mFw.enableFirewall(WHITELIST)); 261 expectIptablesRestoreCommands(disableEnableCommands); 262 263 std::vector<std::string> ifaceCommands = { 264 "*filter\n" 265 "-I fw_INPUT -i rmnet_data0 -j RETURN\n" 266 "-I fw_OUTPUT -o rmnet_data0 -j RETURN\n" 267 "COMMIT\n" 268 }; 269 EXPECT_EQ(0, mFw.setInterfaceRule("rmnet_data0", ALLOW)); 270 expectIptablesRestoreCommands(ifaceCommands); 271 272 EXPECT_EQ(0, mFw.setInterfaceRule("rmnet_data0", ALLOW)); 273 expectIptablesRestoreCommands(noCommands); 274 275 ifaceCommands = { 276 "*filter\n" 277 "-D fw_INPUT -i rmnet_data0 -j RETURN\n" 278 "-D fw_OUTPUT -o rmnet_data0 -j RETURN\n" 279 "COMMIT\n" 280 }; 281 EXPECT_EQ(0, mFw.setInterfaceRule("rmnet_data0", DENY)); 282 expectIptablesRestoreCommands(ifaceCommands); 283 284 EXPECT_EQ(0, mFw.setInterfaceRule("rmnet_data0", DENY)); 285 expectIptablesRestoreCommands(noCommands); 286 287 EXPECT_EQ(0, mFw.enableFirewall(WHITELIST)); 288 expectIptablesRestoreCommands(noCommands); 289 290 EXPECT_EQ(0, mFw.disableFirewall()); 291 expectIptablesRestoreCommands(disableCommands); 292 293 // TODO: calling disableFirewall and then enableFirewall(WHITELIST) does 294 // nothing. This seems like a clear bug. 295 EXPECT_EQ(0, mFw.enableFirewall(WHITELIST)); 296 expectIptablesRestoreCommands(noCommands); 297 } 298