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

Unverified Commit 175e4084 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.

Update restriction rules for an app when it is being updated/replaced,
not only when it is installed for the first time. Use the latest data
when checking for internet permission.

Co-authored-by: default avatarChirayu Desai <chirayudesai1@gmail.com>
Co-authored-by: default avatarTommy Webb <tommy@calyxinstitute.org>
Change-Id2: I608a792e54cad347f4c256029a2959d6f6b45e3b
Change-Id: I5fae5389776196175eba31f646efff6771824dcc
parent d5b59677
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -88,6 +88,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).
+67 −7
Original line number Diff line number Diff line
@@ -97,6 +97,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 +189,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 +493,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;
@@ -947,6 +954,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() {
@@ -1375,14 +1393,30 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
            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) {
                    mInternetPermissionMap.delete(uid);
                    if (!hasInternetPermissionUL(uid) && !isSystemApp(uid)) {
                        Slog.i(TAG, "ACTION_PACKAGE_ADDED for uid=" + uid + ", no INTERNET");
                        addUidPolicy(uid, POLICY_REJECT_ALL);
                    }
                    updateRestrictionRulesForUidUL(uid);
                }
            }
        }

        private boolean isSystemApp(int uid) {
            final String packageName = getPackageForUid(uid);
            if (packageName == null) return false;
            final ApplicationInfo appInfo;
            try {
                appInfo = mContext.getPackageManager().getApplicationInfo(packageName,
                        PackageManager.MATCH_UNINSTALLED_PACKAGES);
            } catch (PackageManager.NameNotFoundException ignored) {
                return false;
            }
            return appInfo.isSystemApp();
        }
    };

    final private BroadcastReceiver mUidRemovedReceiver = new BroadcastReceiver() {
@@ -1394,7 +1428,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) {
@@ -1427,6 +1461,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) {
@@ -3240,7 +3283,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) {
@@ -4695,14 +4738,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;
@@ -4715,7 +4764,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;
@@ -4745,6 +4794,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
@@ -5397,6 +5451,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);
    }

    /**
+14 −4
Original line number Diff line number Diff line
@@ -21502,7 +21502,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                }
            }
            onCreateAndProvisionManagedProfileCompleted(provisioningParams);
            onCreateAndProvisionManagedProfileCompleted(userInfo.id, provisioningParams);
            sendProvisioningCompletedBroadcast(
                    userInfo.id,
@@ -21642,7 +21642,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            @NonNull ManagedProfileProvisioningParams provisioningParams,
            @NonNull UserHandle managedProfileUser
    ) {
        onCreateAndProvisionManagedProfileCompleted(provisioningParams);
        onCreateAndProvisionManagedProfileCompleted(managedProfileUser.getIdentifier(),
                provisioningParams);
        sendProvisioningCompletedBroadcast(
                managedProfileUser.getIdentifier(),
                ACTION_PROVISION_MANAGED_PROFILE,
@@ -21698,8 +21699,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 =