Cap number of NetworkRequests a UID can make to 100
This prevents DoSing ConnectivityService with too many requests.
Fixes: 27253080
Change-Id: Id0480d220b2f01b9ef1146bef8ead2fc8287e28d
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 40d44b4..6856d3f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -2321,6 +2321,18 @@
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
@@ -3668,6 +3680,11 @@
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;
@@ -3728,6 +3745,7 @@
mPid = getCallingPid();
mUid = getCallingUid();
mType = type;
+ enforceRequestCountLimit();
}
NetworkRequestInfo(Messenger m, NetworkRequest r, IBinder binder, NetworkRequestType type) {
@@ -3739,6 +3757,7 @@
mUid = getCallingUid();
mType = type;
mPendingIntent = null;
+ enforceRequestCountLimit();
try {
mBinder.linkToDeath(this, 0);
@@ -3747,6 +3766,16 @@
}
}
+ 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";