diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index dca3b35f14..0748816a89 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -42,7 +42,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.res.Configuration; -import android.content.res.Resources; import android.database.ContentObserver; import android.net.ConnectivityManager; import android.net.ConnectivityManager.PacketKeepalive; @@ -63,6 +62,7 @@ import android.net.NetworkInfo.DetailedState; import android.net.NetworkMisc; import android.net.NetworkQuotaInfo; import android.net.NetworkRequest; +import android.net.NetworkSpecifier; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.Proxy; @@ -102,7 +102,6 @@ import android.text.TextUtils; import android.util.LocalLog; import android.util.LocalLog.ReadOnlyLocalLog; import android.util.Log; -import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; @@ -4007,6 +4006,18 @@ public class ConnectivityService extends IConnectivityManager.Stub 0, 0, thresholds); } + private void ensureValidNetworkSpecifier(NetworkCapabilities nc) { + if (nc == null) { + return; + } + NetworkSpecifier ns = nc.getNetworkSpecifier(); + if (ns == null) { + return; + } + MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns); + ns.assertValidFromUid(Binder.getCallingUid()); + } + @Override public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, Messenger messenger, int timeoutMs, IBinder binder, int legacyType) { @@ -4032,9 +4043,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (timeoutMs < 0) { throw new IllegalArgumentException("Bad timeout specified"); } - - MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( - networkCapabilities.getNetworkSpecifier()); + ensureValidNetworkSpecifier(networkCapabilities); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType, nextNetworkRequestId(), type); @@ -4102,9 +4111,7 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceNetworkRequestPermissions(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); - - MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( - networkCapabilities.getNetworkSpecifier()); + ensureValidNetworkSpecifier(networkCapabilities); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.REQUEST); @@ -4166,9 +4173,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // can't request networks. nc.addCapability(NET_CAPABILITY_FOREGROUND); } - - MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( - networkCapabilities.getNetworkSpecifier()); + ensureValidNetworkSpecifier(networkCapabilities); NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); @@ -4186,9 +4191,7 @@ public class ConnectivityService extends IConnectivityManager.Stub if (!hasWifiNetworkListenPermission(networkCapabilities)) { enforceAccessPermission(); } - - MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier( - networkCapabilities.getNetworkSpecifier()); + ensureValidNetworkSpecifier(networkCapabilities); NetworkRequest networkRequest = new NetworkRequest( new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(), diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 6140a896b1..633a914778 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -1996,6 +1996,40 @@ public class ConnectivityServiceTest extends AndroidTestCase { } } + @SmallTest + public void testNetworkSpecifierUidSpoofSecurityException() { + 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) {} + } + + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + mWiFiNetworkAgent.connect(false); + + UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier(); + NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier( + networkSpecifier).build(); + TestNetworkCallback networkCallback = new TestNetworkCallback(); + try { + mCm.requestNetwork(networkRequest, networkCallback); + fail("Network request with spoofed UID did not throw a SecurityException"); + } catch (SecurityException e) { + // expected + } + } + @SmallTest public void testRegisterDefaultNetworkCallback() throws Exception { final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();