Allow networking on loopback in doze, standby, and powersave.

Restricting networking on loopback is needlessly restrictive
because it doesn't have substantial power impact.

Bug: 30186506
Change-Id: Ibe31aff7c43ae02821fdf4a00b600fb5f5f5bc30
diff --git a/server/FirewallController.cpp b/server/FirewallController.cpp
index 839312d..826cf75 100644
--- a/server/FirewallController.cpp
+++ b/server/FirewallController.cpp
@@ -300,6 +300,9 @@
     std::string commands;
     StringAppendF(&commands, "*filter\n:%s -\n", name);
 
+    // Always allow networking on loopback.
+    StringAppendF(&commands, "-A %s -i lo -o lo -j RETURN\n", name);
+
     // Allow TCP RSTs so we can cleanly close TCP connections of apps that no longer have network
     // access. Both incoming and outgoing RSTs are allowed.
     StringAppendF(&commands, "-A %s -p tcp --tcp-flags RST RST -j RETURN\n", name);
diff --git a/server/FirewallControllerTest.cpp b/server/FirewallControllerTest.cpp
index c1226b2..7d96c61 100644
--- a/server/FirewallControllerTest.cpp
+++ b/server/FirewallControllerTest.cpp
@@ -56,6 +56,7 @@
     std::vector<std::string> expectedRestore4 = {
         "*filter",
         ":fw_whitelist -",
+        "-A fw_whitelist -i lo -o lo -j RETURN",
         "-A fw_whitelist -p tcp --tcp-flags RST RST -j RETURN",
         "-A fw_whitelist -m owner --uid-owner 0-9999 -j RETURN",
         "-A fw_whitelist -j DROP",
@@ -64,6 +65,7 @@
     std::vector<std::string> expectedRestore6 = {
         "*filter",
         ":fw_whitelist -",
+        "-A fw_whitelist -i lo -o lo -j RETURN",
         "-A fw_whitelist -p tcp --tcp-flags RST RST -j RETURN",
         "-A fw_whitelist -p icmpv6 --icmpv6-type packet-too-big -j RETURN",
         "-A fw_whitelist -p icmpv6 --icmpv6-type router-solicitation -j RETURN",
@@ -93,6 +95,7 @@
     std::vector<std::string> expectedRestore = {
         "*filter",
         ":fw_blacklist -",
+        "-A fw_blacklist -i lo -o lo -j RETURN",
         "-A fw_blacklist -p tcp --tcp-flags RST RST -j RETURN",
         "COMMIT\n\x04"
     };
@@ -138,6 +141,7 @@
     std::string expected =
             "*filter\n"
             ":FW_whitechain -\n"
+            "-A FW_whitechain -i lo -o lo -j RETURN\n"
             "-A FW_whitechain -p tcp --tcp-flags RST RST -j RETURN\n"
             "-A FW_whitechain -p icmpv6 --icmpv6-type packet-too-big -j RETURN\n"
             "-A FW_whitechain -p icmpv6 --icmpv6-type router-solicitation -j RETURN\n"
@@ -164,6 +168,7 @@
     std::string expected =
             "*filter\n"
             ":FW_blackchain -\n"
+            "-A FW_blackchain -i lo -o lo -j RETURN\n"
             "-A FW_blackchain -p tcp --tcp-flags RST RST -j RETURN\n"
             "-A FW_blackchain -m owner --uid-owner 10023 -j DROP\n"
             "-A FW_blackchain -m owner --uid-owner 10059 -j DROP\n"
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 0fe6d5f..661680c 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -170,31 +170,31 @@
         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), true, uids, &ret);
     }
     EXPECT_EQ(true, ret);
-    EXPECT_EQ((int) uids.size() + 5, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
-    EXPECT_EQ((int) uids.size() + 11, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
+    EXPECT_EQ((int) uids.size() + 6, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
+    EXPECT_EQ((int) uids.size() + 12, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
     {
         TimedOperation op("Clearing whitelist chain");
         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
     }
     EXPECT_EQ(true, ret);
-    EXPECT_EQ(3, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
-    EXPECT_EQ(3, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
+    EXPECT_EQ(4, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
+    EXPECT_EQ(4, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
 
     {
         TimedOperation op(StringPrintf("Programming %d-UID blacklist chain", kNumUids));
         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, uids, &ret);
     }
     EXPECT_EQ(true, ret);
-    EXPECT_EQ((int) uids.size() + 3, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
-    EXPECT_EQ((int) uids.size() + 3, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
+    EXPECT_EQ((int) uids.size() + 4, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
+    EXPECT_EQ((int) uids.size() + 4, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
 
     {
         TimedOperation op("Clearing blacklist chain");
         mNetd->firewallReplaceUidChain(String16(chainName.c_str()), false, noUids, &ret);
     }
     EXPECT_EQ(true, ret);
-    EXPECT_EQ(3, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
-    EXPECT_EQ(3, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
+    EXPECT_EQ(4, iptablesRuleLineLength(IPTABLES_PATH, chainName.c_str()));
+    EXPECT_EQ(4, iptablesRuleLineLength(IP6TABLES_PATH, chainName.c_str()));
 
     // Check that the call fails if iptables returns an error.
     std::string veryLongStringName = "netd_binder_test_UnacceptablyLongIptablesChainName";