FirewallControllerTest.cpp 13 KB

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