From 56115e5c015e0ab432dc540e829c559d3e207608 Mon Sep 17 00:00:00 2001 From: Aaron Huang Date: Tue, 17 Dec 2019 00:33:18 +0800 Subject: [PATCH 1/2] Remove framework code that has moved to frameworks/libs/net Add srcs to framework and change import path. Remove the codes which are moved to frameworks/libs/net. Bug: 139268426 Bug: 135998869 Bug: 138306002 Bug: 143925787 Test: atest FrameworksNetTests atest FrameworksTelephonyTests atest ./frameworks/opt/net/wifi/tests/wifitests/runtests.sh Change-Id: I067cdc404e5a63947c19cb75069a39ae42faa3c8 Merged-In: Ieb8927f9af7f87a5ae038bd6c7daeb3d70117fef --- core/java/android/net/LinkProperties.java | 76 ++---------------- core/java/android/net/MacAddress.java | 79 ++----------------- core/java/android/net/NetworkUtils.java | 10 --- core/java/android/net/RouteInfo.java | 17 +--- .../android/server/ConnectivityService.java | 2 +- .../java/android/net/LinkPropertiesTest.java | 2 +- .../net/java/android/net/MacAddressTest.java | 12 +-- 7 files changed, 24 insertions(+), 174 deletions(-) diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index d25ee0e69e..732ceb560c 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.LinkPropertiesUtils; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -90,36 +92,6 @@ public final class LinkProperties implements Parcelable { // Indexed by interface name to allow modification and to prevent duplicates being added. private Hashtable mStackedLinks = new Hashtable<>(); - /** - * @hide - */ - public static class CompareResult { - public final List removed = new ArrayList<>(); - public final List added = new ArrayList<>(); - - public CompareResult() {} - - public CompareResult(Collection oldItems, Collection newItems) { - if (oldItems != null) { - removed.addAll(oldItems); - } - if (newItems != null) { - for (T newItem : newItems) { - if (!removed.remove(newItem)) { - added.add(newItem); - } - } - } - } - - @Override - public String toString() { - return "removed=[" + TextUtils.join(",", removed) - + "] added=[" + TextUtils.join(",", added) - + "]"; - } - } - /** * @hide */ @@ -1326,7 +1298,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalInterfaceName(@NonNull LinkProperties target) { - return TextUtils.equals(getInterfaceName(), target.getInterfaceName()); + return LinkPropertiesUtils.isIdenticalInterfaceName(target, this); } /** @@ -1349,10 +1321,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalAddresses(@NonNull LinkProperties target) { - Collection targetAddresses = target.getAddresses(); - Collection sourceAddresses = getAddresses(); - return (sourceAddresses.size() == targetAddresses.size()) ? - sourceAddresses.containsAll(targetAddresses) : false; + return LinkPropertiesUtils.isIdenticalAddresses(target, this); } /** @@ -1364,15 +1333,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalDnses(@NonNull LinkProperties target) { - Collection targetDnses = target.getDnsServers(); - String targetDomains = target.getDomains(); - if (mDomains == null) { - if (targetDomains != null) return false; - } else { - if (!mDomains.equals(targetDomains)) return false; - } - return (mDnses.size() == targetDnses.size()) ? - mDnses.containsAll(targetDnses) : false; + return LinkPropertiesUtils.isIdenticalDnses(target, this); } /** @@ -1425,9 +1386,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage public boolean isIdenticalRoutes(@NonNull LinkProperties target) { - Collection targetRoutes = target.getRoutes(); - return (mRoutes.size() == targetRoutes.size()) ? - mRoutes.containsAll(targetRoutes) : false; + return LinkPropertiesUtils.isIdenticalRoutes(target, this); } /** @@ -1439,8 +1398,7 @@ public final class LinkProperties implements Parcelable { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public boolean isIdenticalHttpProxy(@NonNull LinkProperties target) { - return getHttpProxy() == null ? target.getHttpProxy() == null : - getHttpProxy().equals(target.getHttpProxy()); + return LinkPropertiesUtils.isIdenticalHttpProxy(target, this); } /** @@ -1662,26 +1620,6 @@ public final class LinkProperties implements Parcelable { && isIdenticalCaptivePortalData(target); } - /** - * Compares the addresses in this LinkProperties with another - * LinkProperties, examining only addresses on the base link. - * - * @param target a LinkProperties with the new list of addresses - * @return the differences between the addresses. - * @hide - */ - public @NonNull CompareResult compareAddresses(@Nullable LinkProperties target) { - /* - * Duplicate the LinkAddresses into removed, we will be removing - * address which are common between mLinkAddresses and target - * leaving the addresses that are different. And address which - * are in target but not in mLinkAddresses are placed in the - * addedAddresses. - */ - return new CompareResult<>(mLinkAddresses, - target != null ? target.getLinkAddresses() : null); - } - /** * Compares the DNS addresses in this LinkProperties with another * LinkProperties, examining only DNS addresses on the base link. diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java index 74c9aac05b..0e10c42e61 100644 --- a/core/java/android/net/MacAddress.java +++ b/core/java/android/net/MacAddress.java @@ -20,11 +20,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.MacAddressUtils; import android.net.wifi.WifiInfo; import android.os.Parcel; import android.os.Parcelable; -import com.android.internal.util.BitUtils; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; @@ -33,7 +33,6 @@ import java.net.Inet6Address; import java.net.UnknownHostException; import java.security.SecureRandom; import java.util.Arrays; -import java.util.Random; /** * Representation of a MAC address. @@ -109,20 +108,12 @@ public final class MacAddress implements Parcelable { if (equals(BROADCAST_ADDRESS)) { return TYPE_BROADCAST; } - if (isMulticastAddress()) { + if ((mAddr & MULTICAST_MASK) != 0) { return TYPE_MULTICAST; } return TYPE_UNICAST; } - /** - * @return true if this MacAddress is a multicast address. - * @hide - */ - public boolean isMulticastAddress() { - return (mAddr & MULTICAST_MASK) != 0; - } - /** * @return true if this MacAddress is a locally assigned address. */ @@ -192,7 +183,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static boolean isMacAddress(byte[] addr) { - return addr != null && addr.length == ETHER_ADDR_LEN; + return MacAddressUtils.isMacAddress(addr); } /** @@ -261,26 +252,11 @@ public final class MacAddress implements Parcelable { } private static byte[] byteAddrFromLongAddr(long addr) { - byte[] bytes = new byte[ETHER_ADDR_LEN]; - int index = ETHER_ADDR_LEN; - while (index-- > 0) { - bytes[index] = (byte) addr; - addr = addr >> 8; - } - return bytes; + return MacAddressUtils.byteAddrFromLongAddr(addr); } private static long longAddrFromByteAddr(byte[] addr) { - Preconditions.checkNotNull(addr); - if (!isMacAddress(addr)) { - throw new IllegalArgumentException( - Arrays.toString(addr) + " was not a valid MAC address"); - } - long longAddr = 0; - for (byte b : addr) { - longAddr = (longAddr << 8) + BitUtils.uint8(b); - } - return longAddr; + return MacAddressUtils.longAddrFromByteAddr(addr); } // Internal conversion function equivalent to longAddrFromByteAddr(byteAddrFromStringAddr(addr)) @@ -350,50 +326,7 @@ public final class MacAddress implements Parcelable { * @hide */ public static @NonNull MacAddress createRandomUnicastAddressWithGoogleBase() { - return createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); - } - - /** - * Returns a generated MAC address whose 46 bits, excluding the locally assigned bit and the - * unicast bit, are randomly selected. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @return a random locally assigned, unicast MacAddress. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddress() { - return createRandomUnicastAddress(null, new SecureRandom()); - } - - /** - * Returns a randomly generated MAC address using the given Random object and the same - * OUI values as the given MacAddress. - * - * The locally assigned bit is always set to 1. The multicast bit is always set to 0. - * - * @param base a base MacAddress whose OUI is used for generating the random address. - * If base == null then the OUI will also be randomized. - * @param r a standard Java Random object used for generating the random address. - * @return a random locally assigned MacAddress. - * - * @hide - */ - public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) { - long addr; - if (base == null) { - addr = r.nextLong() & VALID_LONG_MASK; - } else { - addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong()); - } - addr |= LOCALLY_ASSIGNED_MASK; - addr &= ~MULTICAST_MASK; - MacAddress mac = new MacAddress(addr); - if (mac.equals(DEFAULT_MAC_ADDRESS)) { - return createRandomUnicastAddress(base, r); - } - return mac; + return MacAddressUtils.createRandomUnicastAddress(BASE_GOOGLE_MAC, new SecureRandom()); } // Convenience function for working around the lack of byte literals. diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 08cc4e24b2..779f7bc91e 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -31,7 +31,6 @@ import android.util.Pair; import java.io.FileDescriptor; import java.math.BigInteger; import java.net.Inet4Address; -import java.net.Inet6Address; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; @@ -312,15 +311,6 @@ public class NetworkUtils { return new Pair(address, prefixLength); } - /** - * Check if IP address type is consistent between two InetAddress. - * @return true if both are the same type. False otherwise. - */ - public static boolean addressTypeMatches(InetAddress left, InetAddress right) { - return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) || - ((left instanceof Inet6Address) && (right instanceof Inet6Address))); - } - /** * Convert a 32 char hex string into a Inet6Address. * throws a runtime exception if the string isn't 32 chars, isn't hex or can't be diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java index 67bad532cd..2b9e9fe81b 100644 --- a/core/java/android/net/RouteInfo.java +++ b/core/java/android/net/RouteInfo.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; +import android.net.util.NetUtils; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -483,21 +484,7 @@ public final class RouteInfo implements Parcelable { @UnsupportedAppUsage @Nullable public static RouteInfo selectBestRoute(Collection routes, InetAddress dest) { - if ((routes == null) || (dest == null)) return null; - - RouteInfo bestRoute = null; - // pick a longest prefix match under same address type - for (RouteInfo route : routes) { - if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) { - if ((bestRoute != null) && - (bestRoute.mDestination.getPrefixLength() >= - route.mDestination.getPrefixLength())) { - continue; - } - if (route.matches(dest)) bestRoute = route; - } - } - return bestRoute; + return NetUtils.selectBestRoute(routes, dest); } /** diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index f06d500212..376dd667bf 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -89,7 +89,6 @@ import android.net.InetAddresses; import android.net.IpMemoryStore; import android.net.IpPrefix; import android.net.LinkProperties; -import android.net.LinkProperties.CompareResult; import android.net.MatchAllNetworkSpecifier; import android.net.NattSocketKeepalive; import android.net.Network; @@ -124,6 +123,7 @@ import android.net.metrics.IpConnectivityLog; import android.net.metrics.NetworkEvent; import android.net.netlink.InetDiagMessage; import android.net.shared.PrivateDnsConfig; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.net.util.MultinetworkPolicyTracker; import android.net.util.NetdService; import android.os.Binder; diff --git a/tests/net/common/java/android/net/LinkPropertiesTest.java b/tests/net/common/java/android/net/LinkPropertiesTest.java index 3f311c951c..f25fd4daf8 100644 --- a/tests/net/common/java/android/net/LinkPropertiesTest.java +++ b/tests/net/common/java/android/net/LinkPropertiesTest.java @@ -27,8 +27,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.net.LinkProperties.CompareResult; import android.net.LinkProperties.ProvisioningChange; +import android.net.util.LinkPropertiesUtils.CompareResult; import android.system.OsConstants; import android.util.ArraySet; diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java index daf187d015..91c9a2a380 100644 --- a/tests/net/java/android/net/MacAddressTest.java +++ b/tests/net/java/android/net/MacAddressTest.java @@ -22,6 +22,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import android.net.util.MacAddressUtils; + import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; @@ -122,11 +124,11 @@ public class MacAddressTest { for (MacAddress mac : multicastAddresses) { String msg = mac.toString() + " expected to be a multicast address"; - assertTrue(msg, mac.isMulticastAddress()); + assertTrue(msg, MacAddressUtils.isMulticastAddress(mac)); } for (MacAddress mac : unicastAddresses) { String msg = mac.toString() + " expected not to be a multicast address"; - assertFalse(msg, mac.isMulticastAddress()); + assertFalse(msg, MacAddressUtils.isMulticastAddress(mac)); } } @@ -156,7 +158,7 @@ public class MacAddressTest { public void testMacAddressConversions() { final int iterations = 10000; for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); String stringRepr = mac.toString(); byte[] bytesRepr = mac.toByteArray(); @@ -188,7 +190,7 @@ public class MacAddressTest { final String expectedLocalOui = "26:5f:78"; final MacAddress base = MacAddress.fromString(anotherOui + ":0:0:0"); for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(base, r); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(base, r); String stringRepr = mac.toString(); assertTrue(stringRepr + " expected to be a locally assigned address", @@ -199,7 +201,7 @@ public class MacAddressTest { } for (int i = 0; i < iterations; i++) { - MacAddress mac = MacAddress.createRandomUnicastAddress(); + MacAddress mac = MacAddressUtils.createRandomUnicastAddress(); String stringRepr = mac.toString(); assertTrue(stringRepr + " expected to be a locally assigned address", From 246d8d6416114580dd475c629562cdf1eb69afa4 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Thu, 16 Jan 2020 12:17:17 -0800 Subject: [PATCH 2/2] DO NOT MERGE: RELAND: NetworkRequest: Embed requestor uid & packageName Add the requestorUid & requestorPackageName fields to NetworkCapabilities. This is populated by CS when a new network request is received. These 2 requestor fields are also optionally used for network matching. All of the regular app initiated requests will have the requestor uid and package name set by connectivity service. Network agents can optionally set the requestorUid and requestorPackageName to restrict the network created only to the app that requested the network. This will help removing the necessity for the various specifiers to embed the uid & package name info in the specifier for network matching. Note: NetworkSpecifier.assertValidFromUid() is deprecated & removed in favor of setting the uid/package name on the agent to restrict the network to a certain app (useful for wifi peer to peer API & wifi aware). Bug: 144102365 Test: Verified that wifi network request related CTS verifier tests pass. Test: Device boots up and connects to wifi networks Merged-In: I207c446108afdac7ee2c25e6bbcbc37c4e3f6529 Change-Id: I58775e82aa7725aac5aa27ca9d2b5ee8f0be4242 --- .../java/android/net/ConnectivityManager.java | 14 +- .../android/net/IConnectivityManager.aidl | 9 +- .../java/android/net/NetworkCapabilities.java | 161 +++++++++++++++++- core/java/android/net/NetworkRequest.java | 26 +++ .../android/server/ConnectivityService.java | 54 +++--- .../android/net/NetworkCapabilitiesTest.java | 16 +- .../android/net/ConnectivityManagerTest.java | 12 +- .../server/ConnectivityServiceTest.java | 31 +--- 8 files changed, 257 insertions(+), 66 deletions(-) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 6d8565025f..f1b5d3298b 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3747,6 +3747,7 @@ public class ConnectivityManager { checkCallbackNotNull(callback); Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities"); final NetworkRequest request; + final String callingPackageName = mContext.getOpPackageName(); try { synchronized(sCallbacks) { if (callback.networkRequest != null @@ -3758,10 +3759,11 @@ public class ConnectivityManager { Messenger messenger = new Messenger(handler); Binder binder = new Binder(); if (action == LISTEN) { - request = mService.listenForNetwork(need, messenger, binder); + request = mService.listenForNetwork( + need, messenger, binder, callingPackageName); } else { request = mService.requestNetwork( - need, messenger, timeoutMs, binder, legacyType); + need, messenger, timeoutMs, binder, legacyType, callingPackageName); } if (request != null) { sCallbacks.put(request, callback); @@ -4034,8 +4036,10 @@ public class ConnectivityManager { @NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); + final String callingPackageName = mContext.getOpPackageName(); try { - mService.pendingRequestForNetwork(request.networkCapabilities, operation); + mService.pendingRequestForNetwork( + request.networkCapabilities, operation, callingPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (ServiceSpecificException e) { @@ -4147,8 +4151,10 @@ public class ConnectivityManager { @NonNull PendingIntent operation) { printStackTrace(); checkPendingIntentNotNull(operation); + final String callingPackageName = mContext.getOpPackageName(); try { - mService.pendingListenForNetwork(request.networkCapabilities, operation); + mService.pendingListenForNetwork( + request.networkCapabilities, operation, callingPackageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } catch (ServiceSpecificException e) { diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index c871c456dc..3a55461a77 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -166,18 +166,19 @@ interface IConnectivityManager in int factorySerialNumber); NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, - in Messenger messenger, int timeoutSec, in IBinder binder, int legacy); + in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, + String callingPackageName); NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation); + in PendingIntent operation, String callingPackageName); void releasePendingNetworkRequest(in PendingIntent operation); NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities, - in Messenger messenger, in IBinder binder); + in Messenger messenger, in IBinder binder, String callingPackageName); void pendingListenForNetwork(in NetworkCapabilities networkCapabilities, - in PendingIntent operation); + in PendingIntent operation, String callingPackageName); void releaseNetworkRequest(in NetworkRequest networkRequest); diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 38f7390abf..ef4a9e5f3b 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -27,6 +27,7 @@ import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.os.Process; +import android.text.TextUtils; import android.util.ArraySet; import android.util.proto.ProtoOutputStream; @@ -63,6 +64,16 @@ public final class NetworkCapabilities implements Parcelable { // Set to true when private DNS is broken. private boolean mPrivateDnsBroken; + /** + * Uid of the app making the request. + */ + private int mRequestorUid; + + /** + * Package name of the app making the request. + */ + private String mRequestorPackageName; + public NetworkCapabilities() { clearAll(); mNetworkCapabilities = DEFAULT_CAPABILITIES; @@ -89,6 +100,8 @@ public final class NetworkCapabilities implements Parcelable { mOwnerUid = Process.INVALID_UID; mSSID = null; mPrivateDnsBroken = false; + mRequestorUid = Process.INVALID_UID; + mRequestorPackageName = null; } /** @@ -109,6 +122,8 @@ public final class NetworkCapabilities implements Parcelable { mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; mSSID = nc.mSSID; mPrivateDnsBroken = nc.mPrivateDnsBroken; + mRequestorUid = nc.mRequestorUid; + mRequestorPackageName = nc.mRequestorPackageName; } /** @@ -810,7 +825,7 @@ public final class NetworkCapabilities implements Parcelable { } /** - * UID of the app that owns this network, or INVALID_UID if none/unknown. + * UID of the app that owns this network, or Process#INVALID_UID if none/unknown. * *

This field keeps track of the UID of the app that created this network and is in charge of * its lifecycle. This could be the UID of apps such as the Wifi network suggestor, the running @@ -821,8 +836,9 @@ public final class NetworkCapabilities implements Parcelable { /** * Set the UID of the owner app. */ - public void setOwnerUid(final int uid) { + public @NonNull NetworkCapabilities setOwnerUid(final int uid) { mOwnerUid = uid; + return this; } /** @@ -865,9 +881,11 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @SystemApi - public void setAdministratorUids(@NonNull final List administratorUids) { + public @NonNull NetworkCapabilities setAdministratorUids( + @NonNull final List administratorUids) { mAdministratorUids.clear(); mAdministratorUids.addAll(administratorUids); + return this; } /** @@ -1385,6 +1403,7 @@ public final class NetworkCapabilities implements Parcelable { combineSignalStrength(nc); combineUids(nc); combineSSIDs(nc); + combineRequestor(nc); } /** @@ -1404,7 +1423,8 @@ public final class NetworkCapabilities implements Parcelable { && satisfiedBySpecifier(nc) && (onlyImmutable || satisfiedBySignalStrength(nc)) && (onlyImmutable || satisfiedByUids(nc)) - && (onlyImmutable || satisfiedBySSID(nc))); + && (onlyImmutable || satisfiedBySSID(nc))) + && (onlyImmutable || satisfiedByRequestor(nc)); } /** @@ -1488,7 +1508,7 @@ public final class NetworkCapabilities implements Parcelable { public boolean equals(@Nullable Object obj) { if (obj == null || (obj instanceof NetworkCapabilities == false)) return false; NetworkCapabilities that = (NetworkCapabilities) obj; - return (equalsNetCapabilities(that) + return equalsNetCapabilities(that) && equalsTransportTypes(that) && equalsLinkBandwidths(that) && equalsSignalStrength(that) @@ -1496,7 +1516,8 @@ public final class NetworkCapabilities implements Parcelable { && equalsTransportInfo(that) && equalsUids(that) && equalsSSID(that) - && equalsPrivateDnsBroken(that)); + && equalsPrivateDnsBroken(that) + && equalsRequestor(that); } @Override @@ -1514,7 +1535,9 @@ public final class NetworkCapabilities implements Parcelable { + Objects.hashCode(mUids) * 31 + Objects.hashCode(mSSID) * 37 + Objects.hashCode(mTransportInfo) * 41 - + Objects.hashCode(mPrivateDnsBroken) * 43; + + Objects.hashCode(mPrivateDnsBroken) * 43 + + Objects.hashCode(mRequestorUid) * 47 + + Objects.hashCode(mRequestorPackageName) * 53; } @Override @@ -1537,6 +1560,8 @@ public final class NetworkCapabilities implements Parcelable { dest.writeBoolean(mPrivateDnsBroken); dest.writeList(mAdministratorUids); dest.writeInt(mOwnerUid); + dest.writeInt(mRequestorUid); + dest.writeString(mRequestorPackageName); } public static final @android.annotation.NonNull Creator CREATOR = @@ -1559,6 +1584,8 @@ public final class NetworkCapabilities implements Parcelable { netCap.mPrivateDnsBroken = in.readBoolean(); netCap.setAdministratorUids(in.readArrayList(null)); netCap.mOwnerUid = in.readInt(); + netCap.mRequestorUid = in.readInt(); + netCap.mRequestorPackageName = in.readString(); return netCap; } @Override @@ -1624,6 +1651,9 @@ public final class NetworkCapabilities implements Parcelable { sb.append(" Private DNS is broken"); } + sb.append(" RequestorUid: ").append(mRequestorUid); + sb.append(" RequestorPackageName: ").append(mRequestorPackageName); + sb.append("]"); return sb.toString(); } @@ -1632,6 +1662,7 @@ public final class NetworkCapabilities implements Parcelable { private interface NameOf { String nameOf(int value); } + /** * @hide */ @@ -1799,4 +1830,120 @@ public final class NetworkCapabilities implements Parcelable { private boolean equalsPrivateDnsBroken(NetworkCapabilities nc) { return mPrivateDnsBroken == nc.mPrivateDnsBroken; } + + /** + * Set the uid of the app making the request. + * + * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in + * via the public {@link ConnectivityManager} API's will have this field overwritten. + * + * @param uid UID of the app. + * @hide + */ + @SystemApi + public @NonNull NetworkCapabilities setRequestorUid(int uid) { + mRequestorUid = uid; + return this; + } + + /** + * @return the uid of the app making the request. + * + * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} + * object was not obtained from {@link ConnectivityManager}. + * @hide + */ + public int getRequestorUid() { + return mRequestorUid; + } + + /** + * Set the package name of the app making the request. + * + * Note: This works only for {@link NetworkAgent} instances. Any capabilities passed in + * via the public {@link ConnectivityManager} API's will have this field overwritten. + * + * @param packageName package name of the app. + * @hide + */ + @SystemApi + public @NonNull NetworkCapabilities setRequestorPackageName(@NonNull String packageName) { + mRequestorPackageName = packageName; + return this; + } + + /** + * @return the package name of the app making the request. + * + * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained + * from {@link ConnectivityManager}. + * @hide + */ + @Nullable + public String getRequestorPackageName() { + return mRequestorPackageName; + } + + /** + * Set the uid and package name of the app making the request. + * + * Note: This is intended to be only invoked from within connectivitiy service. + * + * @param uid UID of the app. + * @param packageName package name of the app. + * @hide + */ + public @NonNull NetworkCapabilities setRequestorUidAndPackageName( + int uid, @NonNull String packageName) { + return setRequestorUid(uid).setRequestorPackageName(packageName); + } + + /** + * Test whether the passed NetworkCapabilities satisfies the requestor restrictions of this + * capabilities. + * + * This method is called on the NetworkCapabilities embedded in a request with the + * capabilities of an available network. If the available network, sets a specific + * requestor (by uid and optionally package name), then this will only match a request from the + * same app. If either of the capabilities have an unset uid or package name, then it matches + * everything. + *

+ * nc is assumed nonnull. Else, NPE. + */ + private boolean satisfiedByRequestor(NetworkCapabilities nc) { + // No uid set, matches everything. + if (mRequestorUid == Process.INVALID_UID || nc.mRequestorUid == Process.INVALID_UID) { + return true; + } + // uids don't match. + if (mRequestorUid != nc.mRequestorUid) return false; + // No package names set, matches everything + if (null == nc.mRequestorPackageName || null == mRequestorPackageName) return true; + // check for package name match. + return TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName); + } + + /** + * Combine requestor info of the capabilities. + *

+ * This is only legal if either the requestor info of this object is reset, or both info are + * equal. + * nc is assumed nonnull. + */ + private void combineRequestor(@NonNull NetworkCapabilities nc) { + if (mRequestorUid != Process.INVALID_UID && mRequestorUid != nc.mOwnerUid) { + throw new IllegalStateException("Can't combine two uids"); + } + if (mRequestorPackageName != null + && !mRequestorPackageName.equals(nc.mRequestorPackageName)) { + throw new IllegalStateException("Can't combine two package names"); + } + setRequestorUid(nc.mRequestorUid); + setRequestorPackageName(nc.mRequestorPackageName); + } + + private boolean equalsRequestor(NetworkCapabilities nc) { + return mRequestorUid == nc.mRequestorUid + && TextUtils.equals(mRequestorPackageName, nc.mRequestorPackageName); + } } diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java index ee4379a85b..b0bf64ecec 100644 --- a/core/java/android/net/NetworkRequest.java +++ b/core/java/android/net/NetworkRequest.java @@ -380,6 +380,7 @@ public class NetworkRequest implements Parcelable { dest.writeInt(requestId); dest.writeString(type.name()); } + public static final @android.annotation.NonNull Creator CREATOR = new Creator() { public NetworkRequest createFromParcel(Parcel in) { @@ -494,6 +495,31 @@ public class NetworkRequest implements Parcelable { return networkCapabilities.getNetworkSpecifier(); } + /** + * @return the uid of the app making the request. + * + * Note: This could return {@link Process#INVALID_UID} if the {@link NetworkRequest} object was + * not obtained from {@link ConnectivityManager}. + * @hide + */ + @SystemApi + public int getRequestorUid() { + return networkCapabilities.getRequestorUid(); + } + + /** + * @return the package name of the app making the request. + * + * Note: This could return {@code null} if the {@link NetworkRequest} object was not obtained + * from {@link ConnectivityManager}. + * @hide + */ + @SystemApi + @Nullable + public String getRequestorPackageName() { + return networkCapabilities.getRequestorPackageName(); + } + public String toString() { return "NetworkRequest [ " + type + " id=" + requestId + (legacyType != ConnectivityManager.TYPE_NONE ? ", legacyType=" + legacyType : "") + diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index e91918ac6d..52a2ca974d 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -615,7 +615,7 @@ public class ConnectivityService extends IConnectivityManager.Stub private Set mWolSupportedInterfaces; - private TelephonyManager mTelephonyManager; + private final TelephonyManager mTelephonyManager; private final AppOpsManager mAppOpsManager; private final LocationPermissionChecker mLocationPermissionChecker; @@ -966,6 +966,7 @@ public class ConnectivityService extends IConnectivityManager.Stub mDeps = checkNotNull(deps, "missing Dependencies"); mSystemProperties = mDeps.getSystemProperties(); mNetIdManager = mDeps.makeNetIdManager(); + mContext = checkNotNull(context, "missing Context"); mMetricsLog = logger; mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); @@ -995,7 +996,6 @@ public class ConnectivityService extends IConnectivityManager.Stub mLingerDelayMs = mSystemProperties.getInt(LINGER_DELAY_PROPERTY, DEFAULT_LINGER_DELAY_MS); - mContext = checkNotNull(context, "missing Context"); mNMS = checkNotNull(netManager, "missing INetworkManagementService"); mStatsService = checkNotNull(statsService, "missing INetworkStatsService"); mPolicyManager = checkNotNull(policyManager, "missing INetworkPolicyManager"); @@ -1175,6 +1175,7 @@ public class ConnectivityService extends IConnectivityManager.Stub int transportType, NetworkRequest.Type type) { final NetworkCapabilities netCap = new NetworkCapabilities(); netCap.addCapability(NET_CAPABILITY_INTERNET); + netCap.setRequestorUidAndPackageName(Process.myUid(), mContext.getPackageName()); if (transportType > -1) { netCap.addTransportType(transportType); } @@ -1705,10 +1706,12 @@ public class ConnectivityService extends IConnectivityManager.Stub return newLp; } - private void restrictRequestUidsForCaller(NetworkCapabilities nc) { + private void restrictRequestUidsForCallerAndSetRequestorInfo(NetworkCapabilities nc, + int callerUid, String callerPackageName) { if (!checkSettingsPermission()) { - nc.setSingleUid(Binder.getCallingUid()); + nc.setSingleUid(callerUid); } + nc.setRequestorUidAndPackageName(callerUid, callerPackageName); nc.setAdministratorUids(Collections.EMPTY_LIST); // Clear owner UID; this can never come from an app. @@ -5334,7 +5337,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // This checks that the passed capabilities either do not request a // specific SSID/SignalStrength, or the calling app has permission to do so. private void ensureSufficientPermissionsForRequest(NetworkCapabilities nc, - int callerPid, int callerUid) { + int callerPid, int callerUid, String callerPackageName) { if (null != nc.getSSID() && !checkSettingsPermission(callerPid, callerUid)) { throw new SecurityException("Insufficient permissions to request a specific SSID"); } @@ -5344,6 +5347,7 @@ public class ConnectivityService extends IConnectivityManager.Stub throw new SecurityException( "Insufficient permissions to request a specific signal strength"); } + mAppOpsManager.checkPackage(callerUid, callerPackageName); } private ArrayList getSignalStrengthThresholds(NetworkAgentInfo nai) { @@ -5390,7 +5394,6 @@ public class ConnectivityService extends IConnectivityManager.Stub return; } MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns); - ns.assertValidFromUid(Binder.getCallingUid()); } private void ensureValid(NetworkCapabilities nc) { @@ -5402,7 +5405,9 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, - Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { + Messenger messenger, int timeoutMs, IBinder binder, int legacyType, + @NonNull String callingPackageName) { + final int callingUid = Binder.getCallingUid(); final NetworkRequest.Type type = (networkCapabilities == null) ? NetworkRequest.Type.TRACK_DEFAULT : NetworkRequest.Type.REQUEST; @@ -5410,7 +5415,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // the default network request. This allows callers to keep track of // the system default network. if (type == NetworkRequest.Type.TRACK_DEFAULT) { - networkCapabilities = createDefaultNetworkCapabilitiesForUid(Binder.getCallingUid()); + networkCapabilities = createDefaultNetworkCapabilitiesForUid(callingUid); enforceAccessPermission(); } else { networkCapabilities = new NetworkCapabilities(networkCapabilities); @@ -5422,13 +5427,14 @@ public class ConnectivityService extends IConnectivityManager.Stub } ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); + Binder.getCallingPid(), callingUid, callingPackageName); // Set the UID range for this request to the single UID of the requester, or to an empty // set of UIDs if the caller has the appropriate permission and UIDs have not been set. // This will overwrite any allowed UIDs in the requested capabilities. Though there // are no visible methods to set the UIDs, an app could use reflection to try and get // networks for other apps so it's essential that the UIDs are overwritten. - restrictRequestUidsForCaller(networkCapabilities); + restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, + callingUid, callingPackageName); if (timeoutMs < 0) { throw new IllegalArgumentException("Bad timeout specified"); @@ -5503,16 +5509,18 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, - PendingIntent operation) { + PendingIntent operation, @NonNull String callingPackageName) { checkNotNull(operation, "PendingIntent cannot be null."); + final int callingUid = Binder.getCallingUid(); networkCapabilities = new NetworkCapabilities(networkCapabilities); enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); + Binder.getCallingPid(), callingUid, callingPackageName); ensureValidNetworkSpecifier(networkCapabilities); - restrictRequestUidsForCaller(networkCapabilities); + restrictRequestUidsForCallerAndSetRequestorInfo(networkCapabilities, + callingUid, callingPackageName); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.REQUEST); @@ -5560,15 +5568,16 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public NetworkRequest listenForNetwork(NetworkCapabilities networkCapabilities, - Messenger messenger, IBinder binder) { + Messenger messenger, IBinder binder, @NonNull String callingPackageName) { + final int callingUid = Binder.getCallingUid(); if (!hasWifiNetworkListenPermission(networkCapabilities)) { enforceAccessPermission(); } NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); - restrictRequestUidsForCaller(nc); + Binder.getCallingPid(), callingUid, callingPackageName); + restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get // onLost and onAvailable callbacks when networks move in and out of the background. @@ -5588,17 +5597,17 @@ public class ConnectivityService extends IConnectivityManager.Stub @Override public void pendingListenForNetwork(NetworkCapabilities networkCapabilities, - PendingIntent operation) { + PendingIntent operation, @NonNull String callingPackageName) { checkNotNull(operation, "PendingIntent cannot be null."); + final int callingUid = Binder.getCallingUid(); if (!hasWifiNetworkListenPermission(networkCapabilities)) { enforceAccessPermission(); } ensureValid(networkCapabilities); ensureSufficientPermissionsForRequest(networkCapabilities, - Binder.getCallingPid(), Binder.getCallingUid()); - + Binder.getCallingPid(), callingUid, callingPackageName); final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); - restrictRequestUidsForCaller(nc); + restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); @@ -7897,12 +7906,13 @@ public class ConnectivityService extends IConnectivityManager.Stub throw new IllegalArgumentException("ConnectivityManager.TYPE_* are deprecated." + " Please use NetworkCapabilities instead."); } - mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackageName); + final int callingUid = Binder.getCallingUid(); + mAppOpsManager.checkPackage(callingUid, callingPackageName); // This NetworkCapabilities is only used for matching to Networks. Clear out its owner uid // and administrator uids to be safe. final NetworkCapabilities nc = new NetworkCapabilities(request.networkCapabilities); - restrictRequestUidsForCaller(nc); + restrictRequestUidsForCallerAndSetRequestorInfo(nc, callingUid, callingPackageName); final NetworkRequest requestWithId = new NetworkRequest( diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java index 3e4f3d8188..efea91ab91 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java @@ -272,9 +272,23 @@ public class NetworkCapabilitiesTest { netCap.setOwnerUid(123); assertParcelingIsLossless(netCap); netCap.setSSID(TEST_SSID); - assertParcelSane(netCap, 13); + assertParcelSane(netCap, 15); } + @Test + public void testParcelNetworkCapabilitiesWithRequestorUidAndPackageName() { + final NetworkCapabilities netCap = new NetworkCapabilities() + .addCapability(NET_CAPABILITY_INTERNET) + .setRequestorUid(9304) + .setRequestorPackageName("com.android.test") + .addCapability(NET_CAPABILITY_EIMS) + .addCapability(NET_CAPABILITY_NOT_METERED); + assertParcelingIsLossless(netCap); + netCap.setSSID(TEST_SSID); + assertParcelSane(netCap, 15); + } + + @Test public void testOemPaid() { NetworkCapabilities nc = new NetworkCapabilities(); diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java index 7ede14428a..d6bf334ee5 100644 --- a/tests/net/java/android/net/ConnectivityManagerTest.java +++ b/tests/net/java/android/net/ConnectivityManagerTest.java @@ -212,7 +212,8 @@ public class ConnectivityManagerTest { ArgumentCaptor captor = ArgumentCaptor.forClass(Messenger.class); // register callback - when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt())) + when(mService.requestNetwork( + any(), captor.capture(), anyInt(), any(), anyInt(), any())) .thenReturn(request); manager.requestNetwork(request, callback, handler); @@ -240,7 +241,8 @@ public class ConnectivityManagerTest { ArgumentCaptor captor = ArgumentCaptor.forClass(Messenger.class); // register callback - when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt())) + when(mService.requestNetwork( + any(), captor.capture(), anyInt(), any(), anyInt(), any())) .thenReturn(req1); manager.requestNetwork(req1, callback, handler); @@ -258,7 +260,8 @@ public class ConnectivityManagerTest { verify(callback, timeout(100).times(0)).onLosing(any(), anyInt()); // callback can be registered again - when(mService.requestNetwork(any(), captor.capture(), anyInt(), any(), anyInt())) + when(mService.requestNetwork( + any(), captor.capture(), anyInt(), any(), anyInt(), any())) .thenReturn(req2); manager.requestNetwork(req2, callback, handler); @@ -282,7 +285,8 @@ public class ConnectivityManagerTest { info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; when(mCtx.getApplicationInfo()).thenReturn(info); - when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt())).thenReturn(request); + when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any())) + .thenReturn(request); Handler handler = new Handler(Looper.getMainLooper()); manager.requestNetwork(request, callback, handler); diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index a906805d3a..77147c8a35 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -108,6 +108,7 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -311,6 +312,7 @@ public class ConnectivityServiceTest { private static final String MOBILE_IFNAME = "test_rmnet_data0"; private static final String WIFI_IFNAME = "test_wlan0"; private static final String WIFI_WOL_IFNAME = "test_wlan_wol"; + private static final String TEST_PACKAGE_NAME = "com.android.test.package"; private static final String[] EMPTY_STRING_ARRAY = new String[0]; private MockContext mServiceContext; @@ -666,7 +668,7 @@ public class ConnectivityServiceTest { if (mNmValidationRedirectUrl != null) { mNmCallbacks.showProvisioningNotification( - "test_provisioning_notif_action", "com.android.test.package"); + "test_provisioning_notif_action", TEST_PACKAGE_NAME); mNmProvNotificationRequested = true; } } @@ -3039,7 +3041,7 @@ public class ConnectivityServiceTest { networkCapabilities.addTransportType(TRANSPORT_WIFI) .setNetworkSpecifier(new MatchAllNetworkSpecifier()); mService.requestNetwork(networkCapabilities, null, 0, null, - ConnectivityManager.TYPE_WIFI); + ConnectivityManager.TYPE_WIFI, TEST_PACKAGE_NAME); }); class NonParcelableSpecifier extends NetworkSpecifier { @@ -3078,31 +3080,12 @@ public class ConnectivityServiceTest { } @Test - public void testNetworkSpecifierUidSpoofSecurityException() throws Exception { - class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable { - @Override - public boolean satisfiedBy(NetworkSpecifier other) { - return true; - } - - @Override - public void assertValidFromUid(int requestorUid) { - throw new SecurityException("failure"); - } - - @Override - public int describeContents() { return 0; } - @Override - public void writeToParcel(Parcel dest, int flags) {} - } - + public void testNetworkRequestUidSpoofSecurityException() throws Exception { mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); mWiFiNetworkAgent.connect(false); - - UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier(); - NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier( - networkSpecifier).build(); + NetworkRequest networkRequest = newWifiRequestBuilder().build(); TestNetworkCallback networkCallback = new TestNetworkCallback(); + doThrow(new SecurityException()).when(mAppOpsManager).checkPackage(anyInt(), anyString()); assertThrows(SecurityException.class, () -> { mCm.requestNetwork(networkRequest, networkCallback); });