Add Restricted Mode Firewall Chain
Adding new allowlist firewall chain to support restricted networking
mode. See go/restricted-networking-mode.
Bug: b/157505406
Bug: b/170323408
Test: atest NetworkManagementServiceTest
Change-Id: I8e39b3d7b129ad74224d0c1311135b7b48f6514f
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index e9e242e..4f2292e 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -144,6 +144,8 @@
public static final String FIREWALL_CHAIN_NAME_STANDBY = "standby";
/** @hide */
public static final String FIREWALL_CHAIN_NAME_POWERSAVE = "powersave";
+ /** @hide */
+ public static final String FIREWALL_CHAIN_NAME_RESTRICTED = "restricted";
private static final boolean ALLOW_PLATFORM_APP_POLICY = true;
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index c9c318d..181441a 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -24,12 +24,14 @@
import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
import static android.net.INetd.FIREWALL_CHAIN_NONE;
import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
import static android.net.INetd.FIREWALL_DENYLIST;
import static android.net.INetd.FIREWALL_RULE_ALLOW;
import static android.net.INetd.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkStats.SET_DEFAULT;
@@ -218,6 +220,11 @@
*/
@GuardedBy("mRulesLock")
private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray();
+ /**
+ * Contains the per-UID firewall rules that are used when Restricted Networking Mode is enabled.
+ */
+ @GuardedBy("mRulesLock")
+ private SparseIntArray mUidFirewallRestrictedRules = new SparseIntArray();
/** Set of states for the child firewall chains. True if the chain is active. */
@GuardedBy("mRulesLock")
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
@@ -604,9 +611,15 @@
syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby ");
syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable ");
syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave ");
+ syncFirewallChainLocked(FIREWALL_CHAIN_RESTRICTED, "restricted ");
- final int[] chains =
- {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE};
+ final int[] chains = {
+ FIREWALL_CHAIN_STANDBY,
+ FIREWALL_CHAIN_DOZABLE,
+ FIREWALL_CHAIN_POWERSAVE,
+ FIREWALL_CHAIN_RESTRICTED
+ };
+
for (int chain : chains) {
if (getFirewallChainState(chain)) {
setFirewallChainEnabled(chain, true);
@@ -1708,6 +1721,8 @@
return FIREWALL_CHAIN_NAME_DOZABLE;
case FIREWALL_CHAIN_POWERSAVE:
return FIREWALL_CHAIN_NAME_POWERSAVE;
+ case FIREWALL_CHAIN_RESTRICTED:
+ return FIREWALL_CHAIN_NAME_RESTRICTED;
default:
throw new IllegalArgumentException("Bad child chain: " + chain);
}
@@ -1721,6 +1736,8 @@
return FIREWALL_ALLOWLIST;
case FIREWALL_CHAIN_POWERSAVE:
return FIREWALL_ALLOWLIST;
+ case FIREWALL_CHAIN_RESTRICTED:
+ return FIREWALL_ALLOWLIST;
default:
return isFirewallEnabled() ? FIREWALL_ALLOWLIST : FIREWALL_DENYLIST;
}
@@ -1765,6 +1782,9 @@
case FIREWALL_CHAIN_POWERSAVE:
mNetdService.firewallReplaceUidChain("fw_powersave", true, uids);
break;
+ case FIREWALL_CHAIN_RESTRICTED:
+ mNetdService.firewallReplaceUidChain("fw_restricted", true, uids);
+ break;
case FIREWALL_CHAIN_NONE:
default:
Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain);
@@ -1849,6 +1869,8 @@
return mUidFirewallDozableRules;
case FIREWALL_CHAIN_POWERSAVE:
return mUidFirewallPowerSaveRules;
+ case FIREWALL_CHAIN_RESTRICTED:
+ return mUidFirewallRestrictedRules;
case FIREWALL_CHAIN_NONE:
return mUidFirewallRules;
default:
@@ -1923,17 +1945,22 @@
synchronized (mRulesLock) {
dumpUidFirewallRule(pw, "", mUidFirewallRules);
- pw.print("UID firewall standby chain enabled: "); pw.println(
- getFirewallChainState(FIREWALL_CHAIN_STANDBY));
+ pw.print("UID firewall standby chain enabled: ");
+ pw.println(getFirewallChainState(FIREWALL_CHAIN_STANDBY));
dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules);
- pw.print("UID firewall dozable chain enabled: "); pw.println(
- getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
+ pw.print("UID firewall dozable chain enabled: ");
+ pw.println(getFirewallChainState(FIREWALL_CHAIN_DOZABLE));
dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules);
- pw.println("UID firewall powersave chain enabled: " +
- getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
+ pw.print("UID firewall powersave chain enabled: ");
+ pw.println(getFirewallChainState(FIREWALL_CHAIN_POWERSAVE));
dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules);
+
+ pw.print("UID firewall restricted mode chain enabled: ");
+ pw.println(getFirewallChainState(FIREWALL_CHAIN_RESTRICTED));
+ dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_RESTRICTED,
+ mUidFirewallRestrictedRules);
}
synchronized (mIdleTimerLock) {
@@ -2127,6 +2154,11 @@
if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode");
return true;
}
+ if (getFirewallChainState(FIREWALL_CHAIN_RESTRICTED)
+ && mUidFirewallRestrictedRules.get(uid) != FIREWALL_RULE_ALLOW) {
+ if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of restricted mode");
+ return true;
+ }
if (mUidRejectOnMetered.get(uid)) {
if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data"
+ " in the background");
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index 006d78e..5bd352c 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -17,11 +17,13 @@
import static android.net.INetd.FIREWALL_CHAIN_DOZABLE;
import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE;
+import static android.net.INetd.FIREWALL_CHAIN_RESTRICTED;
import static android.net.INetd.FIREWALL_CHAIN_STANDBY;
import static android.net.INetd.FIREWALL_RULE_ALLOW;
import static android.net.INetd.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE;
+import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_RESTRICTED;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.os.Process.INVALID_UID;
@@ -339,6 +341,8 @@
return FIREWALL_CHAIN_NAME_STANDBY;
case FIREWALL_CHAIN_POWERSAVE:
return FIREWALL_CHAIN_NAME_POWERSAVE;
+ case FIREWALL_CHAIN_RESTRICTED:
+ return FIREWALL_CHAIN_NAME_RESTRICTED;
default:
return String.valueOf(chain);
}
diff --git a/tests/net/java/com/android/server/NetworkManagementServiceTest.java b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
index b8b5886..ea763d2 100644
--- a/tests/net/java/com/android/server/NetworkManagementServiceTest.java
+++ b/tests/net/java/com/android/server/NetworkManagementServiceTest.java
@@ -279,11 +279,18 @@
isRestrictedForStandby.put(INetd.FIREWALL_RULE_ALLOW, false);
isRestrictedForStandby.put(INetd.FIREWALL_RULE_DENY, true);
expected.put(INetd.FIREWALL_CHAIN_STANDBY, isRestrictedForStandby);
+ // Restricted mode chain
+ final ArrayMap<Integer, Boolean> isRestrictedForRestrictedMode = new ArrayMap<>();
+ isRestrictedForRestrictedMode.put(NetworkPolicyManager.FIREWALL_RULE_DEFAULT, true);
+ isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_ALLOW, false);
+ isRestrictedForRestrictedMode.put(INetd.FIREWALL_RULE_DENY, true);
+ expected.put(INetd.FIREWALL_CHAIN_RESTRICTED, isRestrictedForRestrictedMode);
final int[] chains = {
INetd.FIREWALL_CHAIN_STANDBY,
INetd.FIREWALL_CHAIN_POWERSAVE,
- INetd.FIREWALL_CHAIN_DOZABLE
+ INetd.FIREWALL_CHAIN_DOZABLE,
+ INetd.FIREWALL_CHAIN_RESTRICTED
};
final int[] states = {
INetd.FIREWALL_RULE_ALLOW,