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

am: eaa8684da7

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

Change-Id: Ic664fa080316eff75dd22fc8e84431cb0eb903be
This commit is contained in:
Paul Jensen
2016-04-21 13:54:53 +00:00
committed by android-build-merger
2 changed files with 122 additions and 0 deletions

View File

@@ -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";

View File

@@ -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);
}
}
}