Institute limit on PhoneStateListener

Limit apps to 50 concurrently registered instances of PhoneStateListener
via TelephonyManager#listen

Test: atest CtsTelephonyTestCases:PhoneStateListenerTest#testListenerLimit
Bug: 151835251
Change-Id: I8486d86773a1e28b4018620c48003855dae75b9d
This commit is contained in:
Hall Liu
2020-03-18 16:24:04 -07:00
parent 5bb02f0890
commit 2da50cfe33
2 changed files with 38 additions and 4 deletions

View File

@@ -64,6 +64,18 @@ public class PhoneStateListener {
private static final String LOG_TAG = "PhoneStateListener";
private static final boolean DBG = false; // STOPSHIP if true
/**
* Limit on registrations of {@link PhoneStateListener}s on a per-pid
* basis. When this limit is exceeded, any calls to {@link TelephonyManager#listen} will fail
* with an {@link IllegalStateException}.
*
* {@link android.os.Process#PHONE_UID}, {@link android.os.Process#SYSTEM_UID}, and the uid that
* TelephonyRegistry runs under are exempt from this limit.
* @hide
*/
public static final int PER_PID_REGISTRATION_LIMIT = 50;
/**
* Stop listening for updates.
*

View File

@@ -39,6 +39,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.telephony.Annotation;
@@ -605,7 +606,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
Record r = add(b);
Record r = add(b, Binder.getCallingPid(), false);
if (r == null) {
return;
@@ -659,7 +660,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
Record r = add(b);
Record r = add(b, Binder.getCallingPid(), false);
if (r == null) {
return;
@@ -789,7 +790,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
synchronized (mRecords) {
// register
IBinder b = callback.asBinder();
Record r = add(b);
boolean shouldEnforceListenerLimit =
Binder.getCallingUid() != Process.SYSTEM_UID
&& Binder.getCallingUid() != Process.PHONE_UID
&& Binder.getCallingUid() != Process.myUid();
Record r = add(b, Binder.getCallingPid(), shouldEnforceListenerLimit);
if (r == null) {
return;
@@ -1084,18 +1089,35 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
return record.canReadCallLog() ? mCallIncomingNumber[phoneId] : "";
}
private Record add(IBinder binder) {
private Record add(IBinder binder, int callingPid, boolean enforceLimit) {
Record r;
synchronized (mRecords) {
final int N = mRecords.size();
// While iterating through the records, keep track of how many we have from this pid.
int numRecordsForPid = 0;
for (int i = 0; i < N; i++) {
r = mRecords.get(i);
if (binder == r.binder) {
// Already existed.
return r;
}
if (r.callerPid == callingPid) {
numRecordsForPid++;
}
}
// If we've exceeded the limit for registrations, log a warning and quit.
if (enforceLimit && numRecordsForPid >= PhoneStateListener.PER_PID_REGISTRATION_LIMIT) {
String errorMsg = "Pid " + callingPid + " has exceeded the number of permissible"
+ "registered listeners. Ignoring request to add.";
loge(errorMsg);
throw new IllegalStateException(errorMsg);
} else if (enforceLimit
&& numRecordsForPid >= PhoneStateListener.PER_PID_REGISTRATION_LIMIT / 2) {
Rlog.w(TAG, "Pid " + callingPid + " has exceeded half the number of permissible"
+ "registered listeners. Now at " + numRecordsForPid);
}
r = new Record();
r.binder = binder;
r.deathRecipient = new TelephonyRegistryDeathRecipient(binder);