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

Commit eedfc545 authored by Paul Jensen's avatar Paul Jensen Committed by android-build-merger
Browse files

Merge "Cap number of NetworkRequests a UID can make to 100" into nyc-dev

am: 3f451053

* commit '3f451053':
  Cap number of NetworkRequests a UID can make to 100

Change-Id: Ic664fa080316eff75dd22fc8e84431cb0eb903be
parents 7ea07312 3f451053
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -2330,6 +2330,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
            if (VDBG || (DBG && nri.isRequest())) log("releasing NetworkRequest " + request);
            nri.unlinkDeathRecipient();
            mNetworkRequests.remove(request);
            synchronized (mUidToNetworkRequestCount) {
                int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
                if (requests < 1) {
                    Slog.wtf(TAG, "BUG: too small request count " + requests + " for UID " +
                            nri.mUid);
                } else if (requests == 1) {
                    mUidToNetworkRequestCount.removeAt(
                            mUidToNetworkRequestCount.indexOfKey(nri.mUid));
                } else {
                    mUidToNetworkRequestCount.put(nri.mUid, requests - 1);
                }
            }
            mNetworkRequestInfoLogs.log("RELEASE " + nri);
            if (nri.isRequest()) {
                // Find all networks that are satisfying this request and remove the request
@@ -3677,6 +3689,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
    private final HashMap<NetworkRequest, NetworkRequestInfo> mNetworkRequests =
            new HashMap<NetworkRequest, NetworkRequestInfo>();

    private static final int MAX_NETWORK_REQUESTS_PER_UID = 100;
    // Map from UID to number of NetworkRequests that UID has filed.
    @GuardedBy("mUidToNetworkRequestCount")
    private final SparseIntArray mUidToNetworkRequestCount = new SparseIntArray();

    private static class NetworkFactoryInfo {
        public final String name;
        public final Messenger messenger;
@@ -3737,6 +3754,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            mPid = getCallingPid();
            mUid = getCallingUid();
            mType = type;
            enforceRequestCountLimit();
        }

        NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) {
@@ -3748,6 +3766,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
            mUid = getCallingUid();
            mType = type;
            mPendingIntent = null;
            enforceRequestCountLimit();

            try {
                mBinder.linkToDeath(this, 0);
@@ -3756,6 +3775,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
            }
        }

        private void enforceRequestCountLimit() {
            synchronized (mUidToNetworkRequestCount) {
                int networkRequests = mUidToNetworkRequestCount.get(mUid, 0) + 1;
                if (networkRequests >= MAX_NETWORK_REQUESTS_PER_UID) {
                    throw new IllegalArgumentException("Too many NetworkRequests filed");
                }
                mUidToNetworkRequestCount.put(mUid, networkRequests);
            }
        }

        private String typeString() {
            switch (mType) {
                case LISTEN: return "Listen";
+1 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
    <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />

    <application>
        <uses-library android:name="android.test.runner" />
+93 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
import com.android.server.net.NetworkPinner;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@@ -1788,4 +1789,96 @@ public class ConnectivityServiceTest extends AndroidTestCase {
        waitFor(cv);
        assertPinnedToWifiWithCellDefault();
    }

    @SmallTest
    public void testNetworkRequestMaximum() {
        final int MAX_REQUESTS = 100;
        // Test that the limit is enforced when MAX_REQUESTS simultaneous requests are added.
        NetworkRequest networkRequest = new NetworkRequest.Builder().build();
        ArrayList<NetworkCallback> networkCallbacks = new ArrayList<NetworkCallback>();
        try {
            for (int i = 0; i < MAX_REQUESTS; i++) {
                NetworkCallback networkCallback = new NetworkCallback();
                mCm.requestNetwork(networkRequest, networkCallback);
                networkCallbacks.add(networkCallback);
            }
            fail("Registering " + MAX_REQUESTS + " NetworkRequests did not throw exception");
        } catch (IllegalArgumentException expected) {}
        for (NetworkCallback networkCallback : networkCallbacks) {
            mCm.unregisterNetworkCallback(networkCallback);
        }
        networkCallbacks.clear();

        try {
            for (int i = 0; i < MAX_REQUESTS; i++) {
                NetworkCallback networkCallback = new NetworkCallback();
                mCm.registerNetworkCallback(networkRequest, networkCallback);
                networkCallbacks.add(networkCallback);
            }
            fail("Registering " + MAX_REQUESTS + " NetworkCallbacks did not throw exception");
        } catch (IllegalArgumentException expected) {}
        for (NetworkCallback networkCallback : networkCallbacks) {
            mCm.unregisterNetworkCallback(networkCallback);
        }
        networkCallbacks.clear();

        ArrayList<PendingIntent> pendingIntents = new ArrayList<PendingIntent>();
        try {
            for (int i = 0; i < MAX_REQUESTS + 1; i++) {
                PendingIntent pendingIntent =
                        PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
                mCm.requestNetwork(networkRequest, pendingIntent);
                pendingIntents.add(pendingIntent);
            }
            fail("Registering " + MAX_REQUESTS +
                    " PendingIntent NetworkRequests did not throw exception");
        } catch (IllegalArgumentException expected) {}
        for (PendingIntent pendingIntent : pendingIntents) {
            mCm.unregisterNetworkCallback(pendingIntent);
        }
        pendingIntents.clear();

        try {
            for (int i = 0; i < MAX_REQUESTS + 1; i++) {
                PendingIntent pendingIntent =
                        PendingIntent.getBroadcast(mContext, 0, new Intent("a" + i), 0);
                mCm.registerNetworkCallback(networkRequest, pendingIntent);
                pendingIntents.add(pendingIntent);
            }
            fail("Registering " + MAX_REQUESTS +
                    " PendingIntent NetworkCallbacks did not throw exception");
        } catch (IllegalArgumentException expected) {}
        for (PendingIntent pendingIntent : pendingIntents) {
            mCm.unregisterNetworkCallback(pendingIntent);
        }
        pendingIntents.clear();
        mService.waitForIdle(5000);

        // Test that the limit is not hit when MAX_REQUESTS requests are added and removed.
        for (int i = 0; i < MAX_REQUESTS; i++) {
            NetworkCallback networkCallback = new NetworkCallback();
            mCm.requestNetwork(networkRequest, networkCallback);
            mCm.unregisterNetworkCallback(networkCallback);
        }
        mService.waitForIdle();
        for (int i = 0; i < MAX_REQUESTS; i++) {
            NetworkCallback networkCallback = new NetworkCallback();
            mCm.registerNetworkCallback(networkRequest, networkCallback);
            mCm.unregisterNetworkCallback(networkCallback);
        }
        mService.waitForIdle();
        for (int i = 0; i < MAX_REQUESTS; i++) {
            PendingIntent pendingIntent =
                    PendingIntent.getBroadcast(mContext, 0, new Intent("b" + i), 0);
            mCm.requestNetwork(networkRequest, pendingIntent);
            mCm.unregisterNetworkCallback(pendingIntent);
        }
        mService.waitForIdle();
        for (int i = 0; i < MAX_REQUESTS; i++) {
            PendingIntent pendingIntent =
                    PendingIntent.getBroadcast(mContext, 0, new Intent("c" + i), 0);
            mCm.registerNetworkCallback(networkRequest, pendingIntent);
            mCm.unregisterNetworkCallback(pendingIntent);
        }
    }
}