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

Commit 23f27778 authored by Qingxi Li's avatar Qingxi Li Committed by android-build-merger
Browse files

Merge "Add API for apps to check if they are the network owner"

am: e021269f

Change-Id: I1316c7fccd9b7a35ff6d8a79a8afa13644d9ab54
parents 1702fe47 e021269f
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -29139,6 +29139,7 @@ package android.net {
    method public int getLinkDownstreamBandwidthKbps();
    method public int getLinkDownstreamBandwidthKbps();
    method public int getLinkUpstreamBandwidthKbps();
    method public int getLinkUpstreamBandwidthKbps();
    method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
    method @Nullable public android.net.NetworkSpecifier getNetworkSpecifier();
    method public int getOwnerUid();
    method public int getSignalStrength();
    method public int getSignalStrength();
    method @Nullable public android.net.TransportInfo getTransportInfo();
    method @Nullable public android.net.TransportInfo getTransportInfo();
    method public boolean hasCapability(int);
    method public boolean hasCapability(int);
@@ -29148,6 +29149,7 @@ package android.net {
    method @NonNull public android.net.NetworkCapabilities setLinkDownstreamBandwidthKbps(int);
    method @NonNull public android.net.NetworkCapabilities setLinkDownstreamBandwidthKbps(int);
    method @NonNull public android.net.NetworkCapabilities setLinkUpstreamBandwidthKbps(int);
    method @NonNull public android.net.NetworkCapabilities setLinkUpstreamBandwidthKbps(int);
    method @NonNull public android.net.NetworkCapabilities setNetworkSpecifier(@NonNull android.net.NetworkSpecifier);
    method @NonNull public android.net.NetworkCapabilities setNetworkSpecifier(@NonNull android.net.NetworkSpecifier);
    method public void setOwnerUid(int);
    method @NonNull public android.net.NetworkCapabilities setSignalStrength(int);
    method @NonNull public android.net.NetworkCapabilities setSignalStrength(int);
    method public void writeToParcel(android.os.Parcel, int);
    method public void writeToParcel(android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
    field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkCapabilities> CREATOR;
+23 −26
Original line number Original line Diff line number Diff line
@@ -26,6 +26,7 @@ import android.net.ConnectivityManager.NetworkCallback;
import android.os.Build;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.Process;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


@@ -58,7 +59,6 @@ import java.util.StringJoiner;
 */
 */
public final class NetworkCapabilities implements Parcelable {
public final class NetworkCapabilities implements Parcelable {
    private static final String TAG = "NetworkCapabilities";
    private static final String TAG = "NetworkCapabilities";
    private static final int INVALID_UID = -1;


    // Set to true when private DNS is broken.
    // Set to true when private DNS is broken.
    private boolean mPrivateDnsBroken;
    private boolean mPrivateDnsBroken;
@@ -85,8 +85,8 @@ public final class NetworkCapabilities implements Parcelable {
        mTransportInfo = null;
        mTransportInfo = null;
        mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
        mSignalStrength = SIGNAL_STRENGTH_UNSPECIFIED;
        mUids = null;
        mUids = null;
        mEstablishingVpnAppUid = INVALID_UID;
        mAdministratorUids.clear();
        mAdministratorUids.clear();
        mOwnerUid = Process.INVALID_UID;
        mSSID = null;
        mSSID = null;
        mPrivateDnsBroken = false;
        mPrivateDnsBroken = false;
    }
    }
@@ -104,8 +104,8 @@ public final class NetworkCapabilities implements Parcelable {
        mTransportInfo = nc.mTransportInfo;
        mTransportInfo = nc.mTransportInfo;
        mSignalStrength = nc.mSignalStrength;
        mSignalStrength = nc.mSignalStrength;
        setUids(nc.mUids); // Will make the defensive copy
        setUids(nc.mUids); // Will make the defensive copy
        mEstablishingVpnAppUid = nc.mEstablishingVpnAppUid;
        setAdministratorUids(nc.mAdministratorUids);
        setAdministratorUids(nc.mAdministratorUids);
        mOwnerUid = nc.mOwnerUid;
        mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
        mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities;
        mSSID = nc.mSSID;
        mSSID = nc.mSSID;
        mPrivateDnsBroken = nc.mPrivateDnsBroken;
        mPrivateDnsBroken = nc.mPrivateDnsBroken;
@@ -810,31 +810,26 @@ public final class NetworkCapabilities implements Parcelable {
    }
    }


    /**
    /**
     * UID of the app that manages this network, or INVALID_UID if none/unknown.
     * UID of the app that owns 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
     * <p>This field keeps track of the UID of the app that created this network and is in charge of
     * of managing it. In the practice, it is used to store the UID of VPN apps so it is named
     * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running
     * accordingly, but it may be renamed if other mechanisms are offered for third party apps
     * VPN, or Carrier Service app managing a cellular data connection.
     * 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;
    private int mOwnerUid = Process.INVALID_UID;


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


    /** @hide */
    /**
    public int getEstablishingVpnAppUid() {
     * Retrieves the UID of the owner app.
        return mEstablishingVpnAppUid;
     */
    public int getOwnerUid() {
        return mOwnerUid;
    }
    }


    /**
    /**
@@ -1157,7 +1152,7 @@ public final class NetworkCapabilities implements Parcelable {
     * member is null, then the network is not restricted by app UID. If it's an empty list, then
     * 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.
     * it means nobody can use it.
     * As a special exception, the app managing this network (as identified by its UID stored in
     * 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
     * mOwnerUid) 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>
     * satisfiedByUids. That still does not mean the network necessarily <strong>applies</strong>
     * to the app that manages it as determined by #appliesToUid.
     * to the app that manages it as determined by #appliesToUid.
     * <p>
     * <p>
@@ -1264,7 +1259,7 @@ public final class NetworkCapabilities implements Parcelable {
     * in the passed nc (representing the UIDs that this network is available to).
     * in the passed nc (representing the UIDs that this network is available to).
     * <p>
     * <p>
     * As a special exception, the UID that created the passed network (as represented by its
     * 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
     * mOwnerUid 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
     * 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.
     * can see its own network when it listens for it.
     * <p>
     * <p>
@@ -1275,7 +1270,7 @@ public final class NetworkCapabilities implements Parcelable {
    public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) {
    public boolean satisfiedByUids(@NonNull NetworkCapabilities nc) {
        if (null == nc.mUids || null == mUids) return true; // The network satisfies everything.
        if (null == nc.mUids || null == mUids) return true; // The network satisfies everything.
        for (UidRange requiredRange : mUids) {
        for (UidRange requiredRange : mUids) {
            if (requiredRange.contains(nc.mEstablishingVpnAppUid)) return true;
            if (requiredRange.contains(nc.mOwnerUid)) return true;
            if (!nc.appliesToUidRange(requiredRange)) {
            if (!nc.appliesToUidRange(requiredRange)) {
                return false;
                return false;
            }
            }
@@ -1541,6 +1536,7 @@ public final class NetworkCapabilities implements Parcelable {
        dest.writeString(mSSID);
        dest.writeString(mSSID);
        dest.writeBoolean(mPrivateDnsBroken);
        dest.writeBoolean(mPrivateDnsBroken);
        dest.writeList(mAdministratorUids);
        dest.writeList(mAdministratorUids);
        dest.writeInt(mOwnerUid);
    }
    }


    public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
    public static final @android.annotation.NonNull Creator<NetworkCapabilities> CREATOR =
@@ -1562,6 +1558,7 @@ public final class NetworkCapabilities implements Parcelable {
                netCap.mSSID = in.readString();
                netCap.mSSID = in.readString();
                netCap.mPrivateDnsBroken = in.readBoolean();
                netCap.mPrivateDnsBroken = in.readBoolean();
                netCap.setAdministratorUids(in.readArrayList(null));
                netCap.setAdministratorUids(in.readArrayList(null));
                netCap.mOwnerUid = in.readInt();
                return netCap;
                return netCap;
            }
            }
            @Override
            @Override
@@ -1611,8 +1608,8 @@ public final class NetworkCapabilities implements Parcelable {
                sb.append(" Uids: <").append(mUids).append(">");
                sb.append(" Uids: <").append(mUids).append(">");
            }
            }
        }
        }
        if (mEstablishingVpnAppUid != INVALID_UID) {
        if (mOwnerUid != Process.INVALID_UID) {
            sb.append(" EstablishingAppUid: ").append(mEstablishingVpnAppUid);
            sb.append(" OwnerUid: ").append(mOwnerUid);
        }
        }


        if (!mAdministratorUids.isEmpty()) {
        if (!mAdministratorUids.isEmpty()) {
+23 −7
Original line number Original line Diff line number Diff line
@@ -1626,7 +1626,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
        return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
        return getNetworkCapabilitiesInternal(getNetworkAgentInfoForNetwork(network));
    }
    }


    private NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
    @VisibleForTesting
    NetworkCapabilities networkCapabilitiesRestrictedForCallerPermissions(
            NetworkCapabilities nc, int callerPid, int callerUid) {
            NetworkCapabilities nc, int callerPid, int callerUid) {
        final NetworkCapabilities newNc = new NetworkCapabilities(nc);
        final NetworkCapabilities newNc = new NetworkCapabilities(nc);
        if (!checkSettingsPermission(callerPid, callerUid)) {
        if (!checkSettingsPermission(callerPid, callerUid)) {
@@ -1637,9 +1638,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
            newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
            newNc.setNetworkSpecifier(newNc.getNetworkSpecifier().redact());
        }
        }
        newNc.setAdministratorUids(Collections.EMPTY_LIST);
        newNc.setAdministratorUids(Collections.EMPTY_LIST);

        maybeSanitizeLocationInfoForCaller(newNc, callerUid);

        return newNc;
        return newNc;
    }
    }


    private void maybeSanitizeLocationInfoForCaller(
            NetworkCapabilities nc, int callerUid) {
        // TODO(b/142072839): Conditionally reset the owner UID if the following
        // conditions are not met:
        // 1. The destination app is the network owner
        // 2. The destination app has the ACCESS_COARSE_LOCATION permission granted
        // if target SDK<29 or otherwise has the ACCESS_FINE_LOCATION permission granted
        // 3. The user's location toggle is on
        nc.setOwnerUid(INVALID_UID);
    }

    private LinkProperties linkPropertiesRestrictedForCallerPermissions(
    private LinkProperties linkPropertiesRestrictedForCallerPermissions(
            LinkProperties lp, int callerPid, int callerUid) {
            LinkProperties lp, int callerPid, int callerUid) {
        if (lp == null) return new LinkProperties();
        if (lp == null) return new LinkProperties();
@@ -1668,6 +1683,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
            nc.setSingleUid(Binder.getCallingUid());
            nc.setSingleUid(Binder.getCallingUid());
        }
        }
        nc.setAdministratorUids(Collections.EMPTY_LIST);
        nc.setAdministratorUids(Collections.EMPTY_LIST);

        // Clear owner UID; this can never come from an app.
        nc.setOwnerUid(INVALID_UID);
    }
    }


    private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
    private void restrictBackgroundRequestForCaller(NetworkCapabilities nc) {
@@ -5795,7 +5813,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
        }


        final Set<UidRange> ranges = nai.networkCapabilities.getUids();
        final Set<UidRange> ranges = nai.networkCapabilities.getUids();
        final int vpnAppUid = nai.networkCapabilities.getEstablishingVpnAppUid();
        final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
        // TODO: this create a window of opportunity for apps to receive traffic between the time
        // TODO: this create a window of opportunity for apps to receive traffic between the time
        // when the old rules are removed and the time when new rules are added. To fix this,
        // when the old rules are removed and the time when new rules are added. To fix this,
        // make eBPF support two whitelisted interfaces so here new rules can be added before the
        // make eBPF support two whitelisted interfaces so here new rules can be added before the
@@ -5994,7 +6012,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        if (nc == null || lp == null) return false;
        if (nc == null || lp == null) return false;
        return nai.isVPN()
        return nai.isVPN()
                && !nai.networkAgentConfig.allowBypass
                && !nai.networkAgentConfig.allowBypass
                && nc.getEstablishingVpnAppUid() != Process.SYSTEM_UID
                && nc.getOwnerUid() != Process.SYSTEM_UID
                && lp.getInterfaceName() != null
                && lp.getInterfaceName() != null
                && (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute());
                && (lp.hasIPv4DefaultRoute() || lp.hasIPv6DefaultRoute());
    }
    }
@@ -6042,12 +6060,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
            // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
            // TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
            // to be removed will never overlap with the new range to be added.
            // to be removed will never overlap with the new range to be added.
            if (wasFiltering && !prevRanges.isEmpty()) {
            if (wasFiltering && !prevRanges.isEmpty()) {
                mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges,
                mPermissionMonitor.onVpnUidRangesRemoved(iface, prevRanges, prevNc.getOwnerUid());
                        prevNc.getEstablishingVpnAppUid());
            }
            }
            if (shouldFilter && !newRanges.isEmpty()) {
            if (shouldFilter && !newRanges.isEmpty()) {
                mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges,
                mPermissionMonitor.onVpnUidRangesAdded(iface, newRanges, newNc.getOwnerUid());
                        newNc.getEstablishingVpnAppUid());
            }
            }
        } catch (Exception e) {
        } catch (Exception e) {
            // Never crash!
            // Never crash!
+1 −1
Original line number Original line Diff line number Diff line
@@ -950,7 +950,7 @@ public class Vpn {
        NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
        NetworkAgentConfig networkAgentConfig = new NetworkAgentConfig();
        networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;
        networkAgentConfig.allowBypass = mConfig.allowBypass && !mLockdown;


        mNetworkCapabilities.setEstablishingVpnAppUid(Binder.getCallingUid());
        mNetworkCapabilities.setOwnerUid(Binder.getCallingUid());
        mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserHandle,
        mNetworkCapabilities.setUids(createUserAndRestrictedProfilesRanges(mUserHandle,
                mConfig.allowedApplications, mConfig.disallowedApplications));
                mConfig.allowedApplications, mConfig.disallowedApplications));
        long token = Binder.clearCallingIdentity();
        long token = Binder.clearCallingIdentity();
+1 −0
Original line number Original line Diff line number Diff line
@@ -269,6 +269,7 @@ public class NetworkCapabilitiesTest {
            .setUids(uids)
            .setUids(uids)
            .addCapability(NET_CAPABILITY_EIMS)
            .addCapability(NET_CAPABILITY_EIMS)
            .addCapability(NET_CAPABILITY_NOT_METERED);
            .addCapability(NET_CAPABILITY_NOT_METERED);
        netCap.setOwnerUid(123);
        assertParcelingIsLossless(netCap);
        assertParcelingIsLossless(netCap);
        netCap.setSSID(TEST_SSID);
        netCap.setSSID(TEST_SSID);
        assertParcelSane(netCap, 13);
        assertParcelSane(netCap, 13);
Loading