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

Unverified Commit 5e23d82b authored by Oliver Scott's avatar Oliver Scott Committed by Michael Bestas
Browse files

Firewall: Network access toggle support



Everything needed to support prohibiting apps' overall network access,
apart from changes for Settings / Firewall app.

"Firewall: Migrate to POLICY_REJECT_ALL" is critical to include, too,
if existing installations with prior implementations must be supported.

Co-authored-by: default avatarChirayu Desai <chirayudesai1@gmail.com>
Co-authored-by: default avatarTommy Webb <tommy@calyxinstitute.org>
Change-Id: I5fae5389776196175eba31f646efff6771824dcc
parent e5a628a7
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -86,6 +86,10 @@ public class NetworkPolicyManager {
     * @hide
     */
    public static final int POLICY_ALLOW_METERED_BACKGROUND = 0x4;
    /** Reject network usage on all networks
     * @hide
     */
    public static final int POLICY_REJECT_ALL = 0x40000;

    /*
     * Rules defining whether an uid has access to a network given its type (metered / non-metered).
+60 −7
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import static android.content.Intent.ACTION_PACKAGE_ADDED;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.ACTION_USER_ADDED;
import static android.content.Intent.ACTION_USER_REMOVED;
import static android.content.Intent.EXTRA_REPLACING;
import static android.content.Intent.EXTRA_UID;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
@@ -97,6 +98,7 @@ import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FOREGROUND_THRESHOLD_STATE;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_ALL;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
import static android.net.NetworkPolicyManager.RULE_NONE;
@@ -188,6 +190,7 @@ import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.NetworkCallback;
import android.net.ConnectivitySettingsManager;
import android.net.INetworkManagementEventObserver;
import android.net.INetworkPolicyListener;
import android.net.INetworkPolicyManager;
@@ -491,6 +494,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {

    private static final String PROP_SUB_PLAN_OWNER = "persist.sys.sub_plan_owner";

    // TODO: this needs to be kept in sync with
    //  ConnectivitySettingsManager#UIDS_ALLOWED_ON_RESTRICTED_NETWORKS
    private static final String UIDS_ALLOWED_ON_RESTRICTED_NETWORKS =
            "uids_allowed_on_restricted_networks";

    private final Context mContext;
    private final IActivityManager mActivityManager;
    private NetworkStatsManager mNetworkStats;
@@ -956,6 +964,17 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        // Expose private service for system components to use.
        LocalServices.addService(NetworkPolicyManagerInternal.class,
                new NetworkPolicyManagerInternalImpl());

        mContext.getContentResolver().registerContentObserver(
                Settings.Global.getUriFor(UIDS_ALLOWED_ON_RESTRICTED_NETWORKS), false,
                new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange) {
                synchronized (mUidRulesFirstLock) {
                    updateRestrictedModeAllowlistUL();
                }
            }
        });
    }

    public void bindConnectivityManager() {
@@ -1394,12 +1413,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            final int uid = intent.getIntExtra(EXTRA_UID, -1);
            if (uid == -1) return;

            if (intent.getBooleanExtra(EXTRA_REPLACING, false)) {
                if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED Not new app, skip it uid=" + uid);
                return;
            }

            if (ACTION_PACKAGE_ADDED.equals(action)) {
                // update rules for UID, since it might be subject to
                // global background data policy
                if (LOGV) Slog.v(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid);
                // Clear the cache for the app
                synchronized (mUidRulesFirstLock) {
                    if (!hasInternetPermissionUL(uid) && !isSystemApp(uid)) {
                        Slog.i(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid + ", no INTERNET");
                        addUidPolicy(uid, POLICY_REJECT_ALL);
                    }
                    mInternetPermissionMap.delete(uid);
                    updateRestrictionRulesForUidUL(uid);
                }
@@ -1416,7 +1443,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            if (uid == -1) return;

            // remove any policy and update rules to clean up
            if (LOGV) Slog.v(TAG, "ACTION_UID_REMOVED for uid=" + uid);
            Slog.i(TAG, "ACTION_UID_REMOVED for uid=" + uid);
            synchronized (mUidRulesFirstLock) {
                onUidDeletedUL(uid);
                synchronized (mNetworkPoliciesSecondLock) {
@@ -1449,6 +1476,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
                        if (action == ACTION_USER_ADDED) {
                            // Add apps that are allowed by default.
                            addDefaultRestrictBackgroundAllowlistUidsUL(userId);
                        } else {
                            synchronized (mUidRulesFirstLock) {
                                for (int i = 0; i < mUidPolicy.size(); i++) {
                                    final int uid = mUidPolicy.keyAt(i);
                                    if (UserHandle.getUserId(uid) == userId) {
                                        mUidPolicy.delete(uid);
                                    }
                                }
                            }
                        }
                        // Update global restrict for that user
                        synchronized (mNetworkPoliciesSecondLock) {
@@ -3252,7 +3288,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        } else {
            mUidPolicy.put(uid, policy);
        }

        updateRestrictedModeForUidUL(uid);
        // uid policy changed, recompute rules and persist policy.
        updateRulesForDataUsageRestrictionsUL(uid);
        if (persist) {
@@ -4710,14 +4746,20 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        if (mRestrictedNetworkingMode) {
            // Note: setUidFirewallRule also updates mUidFirewallRestrictedModeRules.
            // In this case, default firewall rules can also be added.
            long token = Binder.clearCallingIdentity();
            try {
                setUidFirewallRuleUL(FIREWALL_CHAIN_RESTRICTED, uid,
                        getRestrictedModeFirewallRule(effectiveBlockedReasons));
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }
    }

    @GuardedBy("mUidRulesFirstLock")
    private int updateBlockedReasonsForRestrictedModeUL(int uid) {
        final boolean hasRestrictedModeAccess = hasRestrictedModeAccess(uid);
        final boolean hasRestrictedModeAccess = hasRestrictedModeAccess(uid)
                || !isUidBlockedOnAllNetworks(uid);
        final int oldEffectiveBlockedReasons;
        final int newEffectiveBlockedReasons;
        final int uidRules;
@@ -4730,7 +4772,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            } else {
                uidBlockedState.blockedReasons &= ~BLOCKED_REASON_RESTRICTED_MODE;
            }
            if (hasRestrictedModeAccess) {
            if (hasRestrictedModeAccess || !hasInternetPermissionUL(uid)) {
                uidBlockedState.allowedReasons |= ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
            } else {
                uidBlockedState.allowedReasons &= ~ALLOWED_REASON_RESTRICTED_MODE_PERMISSIONS;
@@ -4760,6 +4802,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
        }
    }

    private boolean isUidBlockedOnAllNetworks(int uid) {
        // Check for restricted-networking-mode status
        return (getUidPolicy(uid) & POLICY_REJECT_ALL) == POLICY_REJECT_ALL;
    }

    private boolean hasRestrictedModeAccess(int uid) {
        try {
            // TODO: this needs to be kept in sync with
@@ -5418,6 +5465,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {

        // ...then update iptables asynchronously.
        mHandler.obtainMessage(MSG_RESET_FIREWALL_RULES_BY_UID, uid, 0).sendToTarget();

        Set<Integer> uids =
                ConnectivitySettingsManager.getUidsAllowedOnRestrictedNetworks(mContext);
        uids.remove(uid);
        ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext,
                uids);
    }

    /**
+12 −3
Original line number Diff line number Diff line
@@ -21511,7 +21511,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                }
            }
            onCreateAndProvisionManagedProfileCompleted(provisioningParams);
            onCreateAndProvisionManagedProfileCompleted(userInfo.id, provisioningParams);
            sendProvisioningCompletedBroadcast(
                    userInfo.id,
@@ -21583,8 +21583,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
     *
     * <p>This method is meant to be overridden by OEMs.
     */
    private void onCreateAndProvisionManagedProfileCompleted(
            ManagedProfileProvisioningParams provisioningParams) {}
    private void onCreateAndProvisionManagedProfileCompleted(int userId,
            ManagedProfileProvisioningParams provisioningParams) {
        try {
            Set<Integer> uids = ConnectivitySettingsManager.getUidsAllowedOnRestrictedNetworks(
                    mContext);
            uids.add(mContext.getPackageManager().getPackageUidAsUser(
                    provisioningParams.getOwnerName(), userId));
            ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, uids);
        } catch (NameNotFoundException ignored) {
        }
    }
    private void maybeInstallDevicePolicyManagementRoleHolderInUser(int targetUserId) {
        String devicePolicyManagerRoleHolderPackageName =