From 20e92eca29f7df07c49230a2ec30d0f953a72f12 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Thu, 6 Feb 2020 18:31:19 +0900 Subject: [PATCH] Add combine() and equals() for NetworkCapabilities admin UIDs. NetworkCapabilities#mAdministratorUids should be checked for equality when combining NetworkCapabilities. Administrator UIDs should also be included in NetworkCapabilities equals() and hashCode(). Bug: 147903575 Test: FrameworksNetTests Change-Id: I803bdec80e27ee80d3a39844c5fb7aed584ab07d --- .../java/android/net/NetworkCapabilities.java | 65 +++++++++++++++++-- .../android/net/NetworkCapabilitiesTest.java | 21 ++++++ 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index bf8ba6561a..1fc28bda06 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -16,6 +16,8 @@ package android.net; +import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE; + import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -115,7 +117,7 @@ public final class NetworkCapabilities implements Parcelable { mTransportInfo = nc.mTransportInfo; mSignalStrength = nc.mSignalStrength; setUids(nc.mUids); // Will make the defensive copy - setAdministratorUids(nc.mAdministratorUids); + setAdministratorUids(nc.getAdministratorUids()); mOwnerUid = nc.mOwnerUid; mUnwantedNetworkCapabilities = nc.mUnwantedNetworkCapabilities; mSSID = nc.mSSID; @@ -881,6 +883,9 @@ public final class NetworkCapabilities implements Parcelable { *

For NetworkCapability instances being sent from the System Server, this value MUST be * empty unless the destination is 1) the System Server, or 2) Telephony. In either case, the * receiving entity must have the ACCESS_FINE_LOCATION permission and target R+. + * + *

When received from an app in a NetworkRequest this is always cleared out by the system + * server. This field is never used for matching NetworkRequests to NetworkAgents. */ @NonNull private int[] mAdministratorUids = new int[0]; @@ -889,10 +894,11 @@ public final class NetworkCapabilities implements Parcelable { * *

UIDs included in administratorUids gain administrator privileges over this Network. * Examples of UIDs that should be included in administratorUids are: + * *

* *

In general, user-supplied networks (such as WiFi networks) do not have an administrator. @@ -900,7 +906,10 @@ public final class NetworkCapabilities implements Parcelable { *

An app is granted owner privileges over Networks that it supplies. The owner UID MUST * always be included in administratorUids. * + *

The administrator UIDs are set by network agents. + * * @param administratorUids the UIDs to be set as administrators of this Network. + * @see #mAdministratorUids * @hide */ @NonNull @@ -913,7 +922,12 @@ public final class NetworkCapabilities implements Parcelable { /** * Retrieves the UIDs that are administrators of this Network. * + *

This is only populated in NetworkCapabilities objects that come from network agents for + * networks that are managed by specific apps on the system, such as carrier privileged apps or + * wifi suggestion apps. This will include the network owner. + * * @return the int[] of UIDs that are administrators of this Network + * @see #mAdministratorUids * @hide */ @NonNull @@ -922,6 +936,40 @@ public final class NetworkCapabilities implements Parcelable { return Arrays.copyOf(mAdministratorUids, mAdministratorUids.length); } + /** + * Tests if the set of administrator UIDs of this network is the same as that of the passed one. + * + *

The administrator UIDs must be in sorted order. + * + *

nc is assumed non-null. Else, NPE. + * + * @hide + */ + @VisibleForTesting(visibility = PRIVATE) + public boolean equalsAdministratorUids(@NonNull final NetworkCapabilities nc) { + return Arrays.equals(mAdministratorUids, nc.mAdministratorUids); + } + + /** + * Combine the administrator UIDs of the capabilities. + * + *

This is only legal if either of the administrators lists are empty, or if they are equal. + * Combining administrator UIDs is only possible for combining non-overlapping sets of UIDs. + * + *

If both administrator lists are non-empty but not equal, they conflict with each other. In + * this case, it would not make sense to add them together. + */ + private void combineAdministratorUids(@NonNull final NetworkCapabilities nc) { + if (nc.mAdministratorUids.length == 0) return; + if (mAdministratorUids.length == 0) { + mAdministratorUids = Arrays.copyOf(nc.mAdministratorUids, nc.mAdministratorUids.length); + return; + } + if (!equalsAdministratorUids(nc)) { + throw new IllegalStateException("Can't combine two different administrator UID lists"); + } + } + /** * Value indicating that link bandwidth is unspecified. * @hide @@ -1426,6 +1474,7 @@ public final class NetworkCapabilities implements Parcelable { combineUids(nc); combineSSIDs(nc); combineRequestor(nc); + combineAdministratorUids(nc); } /** @@ -1539,7 +1588,8 @@ public final class NetworkCapabilities implements Parcelable { && equalsUids(that) && equalsSSID(that) && equalsPrivateDnsBroken(that) - && equalsRequestor(that); + && equalsRequestor(that) + && equalsAdministratorUids(that); } @Override @@ -1559,7 +1609,8 @@ public final class NetworkCapabilities implements Parcelable { + Objects.hashCode(mTransportInfo) * 41 + Objects.hashCode(mPrivateDnsBroken) * 43 + Objects.hashCode(mRequestorUid) * 47 - + Objects.hashCode(mRequestorPackageName) * 53; + + Objects.hashCode(mRequestorPackageName) * 53 + + Arrays.hashCode(mAdministratorUids) * 59; } @Override @@ -1580,7 +1631,7 @@ public final class NetworkCapabilities implements Parcelable { dest.writeArraySet(mUids); dest.writeString(mSSID); dest.writeBoolean(mPrivateDnsBroken); - dest.writeIntArray(mAdministratorUids); + dest.writeIntArray(getAdministratorUids()); dest.writeInt(mOwnerUid); dest.writeInt(mRequestorUid); dest.writeString(mRequestorPackageName); diff --git a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java index 9fe1883010..0751218809 100644 --- a/tests/net/common/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/common/java/android/net/NetworkCapabilitiesTest.java @@ -58,6 +58,7 @@ import androidx.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.Arrays; import java.util.Set; @RunWith(AndroidJUnit4.class) @@ -280,6 +281,7 @@ public class NetworkCapabilitiesTest { .addCapability(NET_CAPABILITY_NOT_METERED); if (isAtLeastR()) { netCap.setOwnerUid(123); + netCap.setAdministratorUids(new int[] {5, 11}); } assertParcelingIsLossless(netCap); netCap.setSSID(TEST_SSID); @@ -489,6 +491,25 @@ public class NetworkCapabilitiesTest { assertFalse(nc2.appliesToUid(12)); assertTrue(nc1.appliesToUid(22)); assertTrue(nc2.appliesToUid(22)); + + final int[] adminUids = {3, 6, 12}; + nc1.setAdministratorUids(adminUids); + nc2.combineCapabilities(nc1); + assertTrue(nc2.equalsAdministratorUids(nc1)); + assertArrayEquals(nc2.getAdministratorUids(), adminUids); + + final int[] adminUidsOtherOrder = {3, 12, 6}; + nc1.setAdministratorUids(adminUids); + assertTrue(nc2.equalsAdministratorUids(nc1)); + + final int[] adminUids2 = {11, 1, 12, 3, 6}; + nc1.setAdministratorUids(adminUids2); + assertFalse(nc2.equalsAdministratorUids(nc1)); + assertFalse(Arrays.equals(nc2.getAdministratorUids(), adminUids2)); + try { + nc2.combineCapabilities(nc1); + fail("Shouldn't be able to combine different lists of admin UIDs"); + } catch (IllegalStateException expected) { } } @Test