summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Hui Yu <huiyu@google.com> 2022-07-11 10:01:00 -0700
committer Hui Yu <huiyu@google.com> 2022-07-11 13:59:35 -0700
commit292f9373007d54ccb482a632298accd1a5bcb2d4 (patch)
tree4655d1dd3c2fb600ecf3de2cae893c6e6303303b
parentb37c41d36b777d144d0433b2a16702844cbbc35b (diff)
Limit the max number of service connection a process can bind to
services to be 3000. This limits the max number of outgoing ServiceConnection a process is allowed to bind to a service (or multiple services) by bindService() calls. 1. Add device_config key "max_service_connections_per_process" to set mMaxServiceConnectionsPerProcess, the default value is 3000. 2. If the per process max session connection is exceeded, Context.bindService() calls returns false and the service connection is not connected. Bug: 236039413 Test: atest cts/tests/app/src/android/app/cts/ServiceTest.java#testMaxServiceConnections Change-Id: I9a4e97a4edaa8f2a52bf67b19ce3948d0ebcfdea
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java23
2 files changed, 31 insertions, 2 deletions
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 8368b4dfe070..61c0c75d6965 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2855,6 +2855,14 @@ public final class ActiveServices {
return -1;
}
ServiceRecord s = res.record;
+ final AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
+ final ProcessServiceRecord clientPsr = b.client.mServices;
+ if (clientPsr.numberOfConnections() >= mAm.mConstants.mMaxServiceConnectionsPerProcess) {
+ Slog.w(TAG, "bindService exceeded max service connection number per process, "
+ + "callerApp:" + callerApp.processName
+ + " intent:" + service);
+ return 0;
+ }
// The package could be frozen (meaning it's doing surgery), defer the actual
// binding until the package is unfrozen.
@@ -2905,7 +2913,6 @@ public final class ActiveServices {
mAm.grantImplicitAccess(callerApp.userId, service,
callerApp.uid, UserHandle.getAppId(s.appInfo.uid));
- AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
ConnectionRecord c = new ConnectionRecord(b, activity,
connection, flags, clientLabel, clientIntent,
callerApp.uid, callerApp.processName, callingPackage, res.aliasComponent);
@@ -2916,7 +2923,6 @@ public final class ActiveServices {
if (activity != null) {
activity.addConnection(c);
}
- final ProcessServiceRecord clientPsr = b.client.mServices;
clientPsr.addConnection(c);
c.startAssociationIfNeeded();
if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index c3720965e7f6..13a13f2f4b3c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -196,6 +196,8 @@ final class ActivityManagerConstants extends ContentObserver {
static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000;
static final boolean DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE = true;
+ static final int DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS = 3000;
+
/**
* Same as {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED}
*/
@@ -335,6 +337,9 @@ final class ActivityManagerConstants extends ContentObserver {
private static final String KEY_SERVICE_BIND_ALMOST_PERCEPTIBLE_TIMEOUT_MS =
"service_bind_almost_perceptible_timeout_ms";
+ private static final String KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS =
+ "max_service_connections_per_process";
+
// Maximum number of cached processes we will allow.
public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES;
@@ -687,6 +692,12 @@ final class ActivityManagerConstants extends ContentObserver {
*/
volatile String mComponentAliasOverrides = DEFAULT_COMPONENT_ALIAS_OVERRIDES;
+ /**
+ * The max number of outgoing ServiceConnection a process is allowed to bind to a service
+ * (or multiple services).
+ */
+ volatile int mMaxServiceConnectionsPerProcess = DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS;
+
private final ActivityManagerService mService;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -990,6 +1001,9 @@ final class ActivityManagerConstants extends ContentObserver {
case KEY_NETWORK_ACCESS_TIMEOUT_MS:
updateNetworkAccessTimeoutMs();
break;
+ case KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS:
+ updateMaxServiceConnectionsPerProcess();
+ break;
default:
break;
}
@@ -1633,6 +1647,13 @@ final class ActivityManagerConstants extends ContentObserver {
}
}
+ private void updateMaxServiceConnectionsPerProcess() {
+ mMaxServiceConnectionsPerProcess = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS,
+ DEFAULT_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
+ }
+
@NeverCompile // Avoid size overhead of debugging code.
void dump(PrintWriter pw) {
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
@@ -1779,6 +1800,8 @@ final class ActivityManagerConstants extends ContentObserver {
pw.print("="); pw.println(mServiceBindAlmostPerceptibleTimeoutMs);
pw.print(" "); pw.print(KEY_NETWORK_ACCESS_TIMEOUT_MS);
pw.print("="); pw.println(mNetworkAccessTimeoutMs);
+ pw.print(" "); pw.print(KEY_MAX_SERVICE_CONNECTIONS_PER_PROCESS);
+ pw.print("="); pw.println(mMaxServiceConnectionsPerProcess);
pw.println();
if (mOverrideMaxCachedProcesses >= 0) {