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

Commit f474fc3a authored by Chalard Jean's avatar Chalard Jean
Browse files

Make sure listen requests from VPN apps see their own networks

Test: runtest frameworks-net
Test: CTS pass, including with the next patch which is what this
      actually matters for

Change-Id: I09a94042acbefa24ab884f95326e30d6ab280b82
parent 0b214afb
Loading
Loading
Loading
Loading
+45 −4
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import java.util.StringJoiner;
 */
public final class NetworkCapabilities implements Parcelable {
    private static final String TAG = "NetworkCapabilities";
    private static final int INVALID_UID = -1;

    /**
     * @hide
@@ -67,6 +68,7 @@ public final class NetworkCapabilities implements Parcelable {
            mNetworkSpecifier = nc.mNetworkSpecifier;
            mSignalStrength = nc.mSignalStrength;
            mUids = nc.mUids;
            mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid;
        }
    }

@@ -81,6 +83,7 @@ public final class NetworkCapabilities implements Parcelable {
        mNetworkSpecifier = null;
        mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
        mUids = null;
        mEstablishingVpnAppUid = INVALID_UID;
    }

    /**
@@ -622,6 +625,29 @@ public final class NetworkCapabilities implements Parcelable {
        return (nc.mTransportTypes == this.mTransportTypes);
    }

    /**
     * UID of the app that manages this network, or INVALID_UID if none/unknown.
     *
     * This field keeps track of the UID of the app that created this network and is in charge
     * of managing it. In the practice, it is used to store the UID of VPN apps so it is named
     * accordingly, but it may be renamed if other mechanisms are offered for third party apps
     * to create networks.
     *
     * Because this field is only used in the services side (and to avoid apps being able to
     * set this to whatever they want), this field is not parcelled and will not be conserved
     * across the IPC boundary.
     * @hide
     */
    private int mEstablishingVpnAppUid = INVALID_UID;

    /**
     * Set the UID of the managing app.
     * @hide
     */
    public void setEstablishingVpnAppUid(final int uid) {
        mEstablishingVpnAppUid = uid;
    }

    /**
     * Value indicating that link bandwidth is unspecified.
     * @hide
@@ -848,6 +874,10 @@ public final class NetworkCapabilities implements Parcelable {
     * bypass the VPN can do so iff the VPN app allows them to or if they are privileged. If this
     * member is null, then the network is not restricted by app UID. If it's an empty list, then
     * it means nobody can use it.
     * As a special exception, the app managing this network (as identified by its UID stored in
     * mEstablishingVpnAppUid) can always see this network. This is embodied by a special check in
     * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong>
     * to the app that manages it as determined by #appliesToUid.
     * <p>
     * Please note that in principle a single app can be associated with multiple UIDs because
     * each app will have a different UID when it's run as a different (macro-)user. A single
@@ -935,9 +965,17 @@ public final class NetworkCapabilities implements Parcelable {
    /**
     * Test whether the passed NetworkCapabilities satisfies the UIDs this capabilities require.
     *
     * This is called on the NetworkCapabilities embedded in a request with the capabilities
     * of an available network.
     * nc is assumed nonnull.
     * This method is called on the NetworkCapabilities embedded in a request with the
     * capabilities of an available network. It checks whether all the UIDs from this listen
     * (representing the UIDs that must have access to the network) are satisfied by the UIDs
     * in the passed nc (representing the UIDs that this network is available to).
     * <p>
     * As a special exception, the UID that created the passed network (as represented by its
     * mEstablishingVpnAppUid field) always satisfies a NetworkRequest requiring it (of LISTEN
     * or REQUEST types alike), even if the network does not apply to it. That is so a VPN app
     * can see its own network when it listens for it.
     * <p>
     * nc is assumed nonnull. Else, NPE.
     * @see #appliesToUid
     * @hide
     */
@@ -945,6 +983,7 @@ public final class NetworkCapabilities implements Parcelable {
        if (null == nc.mUids) return true; // The network satisfies everything.
        if (null == mUids) return false; // Not everything allowed but requires everything
        for (UidRange requiredRange : mUids) {
            if (requiredRange.contains(nc.mEstablishingVpnAppUid)) return true;
            if (!nc.appliesToUidRange(requiredRange)) {
                return false;
            }
@@ -1181,8 +1220,10 @@ public final class NetworkCapabilities implements Parcelable {

        String uids = (null != mUids ? " Uids: <" + mUids + ">" : "");

        String establishingAppUid = " EstablishingAppUid: " + mEstablishingVpnAppUid;

        return "[" + transports + capabilities + upBand + dnBand + specifier + signalStrength
            + uids + "]";
            + uids + establishingAppUid + "]";
    }

    /**
+1 −0
Original line number Diff line number Diff line
@@ -844,6 +844,7 @@ public class Vpn {
        NetworkMisc networkMisc = new NetworkMisc();
        networkMisc.allowBypass = mConfig.allowBypass && !mLockdown;

        mNetworkCapabilities.setEstablishingVpnAppUid(Binder.getCallingUid());
        mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserHandle,
                mConfig.allowedApplications, mConfig.disallowedApplications));
        long token = Binder.clearCallingIdentity();