Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9aabc50e authored by Patrick Rohr's avatar Patrick Rohr
Browse files

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
parent 73a74fa6
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ public class NetworkPolicyManager {
    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;

+40 −8
Original line number Diff line number Diff line
@@ -24,12 +24,14 @@ import static android.net.INetd.FIREWALL_ALLOWLIST;
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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
     */
    @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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
            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,
                    FIREWALL_CHAIN_RESTRICTED
            };

            final int[] chains =
                    {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE};
            for (int chain : chains) {
                if (getFirewallChainState(chain)) {
                    setFirewallChainEnabled(chain, true);
@@ -1708,6 +1721,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                    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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
        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 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
                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");
+4 −0
Original line number Diff line number Diff line
@@ -17,11 +17,13 @@ package com.android.server.net;

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 @@ public class NetworkPolicyLogger {
                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);
        }
+8 −1
Original line number Diff line number Diff line
@@ -279,11 +279,18 @@ public class NetworkManagementServiceTest {
        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,