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

Commit 487ffe7d authored by Paul Jensen's avatar Paul Jensen
Browse files

Fix NOT_RESTRICTED network capability and enforce it.

With this change:
1. NOT_RESTRICTED should be removed from NetworkRequests that bring up
   special restricted carrier networks (e.g. IMS, FOTA).
2. NetworkRequests without NOT_RESTRICTED require CONNECTIVITY_INTERNAL
   permission to register
3. Binding sockets to networks without NOT_RESTRICTED requires
   CONNECTIVITY_INTERNAL permission

Bug:21637535
Change-Id: I5991d39facaa6b690e969fe15dcbeec52e918321
parent 532737df
Loading
Loading
Loading
Loading
+2 −37
Original line number Diff line number Diff line
@@ -956,41 +956,6 @@ public class ConnectivityManager {
        return 1;
    }

    /**
     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
     * NetworkCapabilities object if all the capabilities it provides are
     * typically provided by restricted networks.
     *
     * TODO: consider:
     * - Moving to NetworkCapabilities
     * - Renaming it to guessRestrictedCapability and make it set the
     *   restricted capability bit in addition to clearing it.
     * @hide
     */
    public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
        for (int capability : nc.getCapabilities()) {
            switch (capability) {
                case NetworkCapabilities.NET_CAPABILITY_CBS:
                case NetworkCapabilities.NET_CAPABILITY_DUN:
                case NetworkCapabilities.NET_CAPABILITY_EIMS:
                case NetworkCapabilities.NET_CAPABILITY_FOTA:
                case NetworkCapabilities.NET_CAPABILITY_IA:
                case NetworkCapabilities.NET_CAPABILITY_IMS:
                case NetworkCapabilities.NET_CAPABILITY_RCS:
                case NetworkCapabilities.NET_CAPABILITY_XCAP:
                case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED: //there by default
                    continue;
                default:
                    // At least one capability usually provided by unrestricted
                    // networks. Conclude that this network is unrestricted.
                    return;
            }
        }
        // All the capabilities are typically provided by restricted networks.
        // Conclude that this network is restricted.
        nc.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
    }

    private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
        if (networkType == TYPE_MOBILE) {
            int cap = -1;
@@ -1013,14 +978,14 @@ public class ConnectivityManager {
            }
            NetworkCapabilities netCap = new NetworkCapabilities();
            netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR).addCapability(cap);
            maybeMarkCapabilitiesRestricted(netCap);
            netCap.maybeMarkCapabilitiesRestricted();
            return netCap;
        } else if (networkType == TYPE_WIFI) {
            if ("p2p".equals(feature)) {
                NetworkCapabilities netCap = new NetworkCapabilities();
                netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
                netCap.addCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
                maybeMarkCapabilitiesRestricted(netCap);
                netCap.maybeMarkCapabilitiesRestricted();
                return netCap;
            }
        }
+39 −4
Original line number Diff line number Diff line
@@ -38,10 +38,7 @@ public final class NetworkCapabilities implements Parcelable {
     */
    public NetworkCapabilities() {
        clearAll();
        mNetworkCapabilities =
                (1 << NET_CAPABILITY_NOT_RESTRICTED) |
                (1 << NET_CAPABILITY_TRUSTED) |
                (1 << NET_CAPABILITY_NOT_VPN);
        mNetworkCapabilities = DEFAULT_CAPABILITIES;
    }

    public NetworkCapabilities(NetworkCapabilities nc) {
@@ -186,6 +183,28 @@ public final class NetworkCapabilities implements Parcelable {
    private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
    private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_CAPTIVE_PORTAL;

    /**
     * Capabilities that are set by default when the object is constructed.
     */
    private static final long DEFAULT_CAPABILITIES =
            (1 << NET_CAPABILITY_NOT_RESTRICTED) |
            (1 << NET_CAPABILITY_TRUSTED) |
            (1 << NET_CAPABILITY_NOT_VPN);

    /**
     * Capabilities that suggest that a network is restricted.
     * {@see #maybeMarkCapabilitiesRestricted}.
     */
    private static final long RESTRICTED_CAPABILITIES =
            (1 << NET_CAPABILITY_CBS) |
            (1 << NET_CAPABILITY_DUN) |
            (1 << NET_CAPABILITY_EIMS) |
            (1 << NET_CAPABILITY_FOTA) |
            (1 << NET_CAPABILITY_IA) |
            (1 << NET_CAPABILITY_IMS) |
            (1 << NET_CAPABILITY_RCS) |
            (1 << NET_CAPABILITY_XCAP);

    /**
     * Adds the given capability to this {@code NetworkCapability} instance.
     * Multiple capabilities may be applied sequentially.  Note that when searching
@@ -268,6 +287,22 @@ public final class NetworkCapabilities implements Parcelable {
        return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
    }

    /**
     * Removes the NET_CAPABILITY_NOT_RESTRICTED capability if all the capabilities it provides are
     * typically provided by restricted networks.
     *
     * TODO: consider:
     * - Renaming it to guessRestrictedCapability and make it set the
     *   restricted capability bit in addition to clearing it.
     * @hide
     */
    public void maybeMarkCapabilitiesRestricted() {
        // If all the capabilities are typically provided by restricted networks, conclude that this
        // network is restricted.
        if ((mNetworkCapabilities & ~(DEFAULT_CAPABILITIES | RESTRICTED_CAPABILITIES)) == 0)
            removeCapability(NET_CAPABILITY_NOT_RESTRICTED);
    }

    /**
     * Representing the transport type.  Apps should generally not care about transport.  A
     * request for a fast internet connection could be satisfied by a number of different
+7 −1
Original line number Diff line number Diff line
@@ -83,7 +83,13 @@ public class NetworkRequest implements Parcelable {
         * Build {@link NetworkRequest} give the current set of capabilities.
         */
        public NetworkRequest build() {
            return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
            // Make a copy of mNetworkCapabilities so we don't inadvertently remove NOT_RESTRICTED
            // when later an unrestricted capability could be added to mNetworkCapabilities, in
            // which case NOT_RESTRICTED should be returned to mNetworkCapabilities, which
            // maybeMarkCapabilitiesRestricted() doesn't add back.
            final NetworkCapabilities nc = new NetworkCapabilities(mNetworkCapabilities);
            nc.maybeMarkCapabilitiesRestricted();
            return new NetworkRequest(nc, ConnectivityManager.TYPE_NONE,
                    ConnectivityManager.REQUEST_ID_UNSET);
        }

+10 −1
Original line number Diff line number Diff line
@@ -388,8 +388,10 @@ interface INetworkManagementService

    /**
     * Setup a new physical network.
     * @param permission null if no permissions required to access this network.  PERMISSION_NETWORK
     *                   or PERMISSION_SYSTEM to set respective permission.
     */
    void createPhysicalNetwork(int netId);
    void createPhysicalNetwork(int netId, String permission);

    /**
     * Setup a new VPN.
@@ -416,6 +418,13 @@ interface INetworkManagementService
    void setDefaultNetId(int netId);
    void clearDefaultNetId();

    /**
     * Set permission for a network.
     * @param permission null to clear permissions. PERMISSION_NETWORK or PERMISSION_SYSTEM to set
     *                   permission.
     */
    void setNetworkPermission(int netId, String permission);

    void setPermission(String permission, in int[] uids);
    void clearPermission(in int[] uids);

+14 −1
Original line number Diff line number Diff line
@@ -4021,6 +4021,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
        if (!Objects.equals(nai.networkCapabilities, networkCapabilities)) {
            final int oldScore = nai.getCurrentScore();
            if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) !=
                    networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
                try {
                    mNetd.setNetworkPermission(nai.network.netId,
                            networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) ?
                                    null : NetworkManagementService.PERMISSION_SYSTEM);
                } catch (RemoteException e) {
                    loge("Exception in setNetworkPermission: " + e);
                }
            }
            synchronized (nai) {
                nai.networkCapabilities = networkCapabilities;
            }
@@ -4456,7 +4466,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
                            (networkAgent.networkMisc == null ||
                                !networkAgent.networkMisc.allowBypass));
                } else {
                    mNetd.createPhysicalNetwork(networkAgent.network.netId);
                    mNetd.createPhysicalNetwork(networkAgent.network.netId,
                            networkAgent.networkCapabilities.hasCapability(
                                    NET_CAPABILITY_NOT_RESTRICTED) ?
                                    null : NetworkManagementService.PERMISSION_SYSTEM);
                }
            } catch (Exception e) {
                loge("Error creating network " + networkAgent.network.netId + ": "
Loading