diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java index 1e3e6a5b5a..44379264e5 100644 --- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java +++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java @@ -104,6 +104,10 @@ public class KeepaliveTracker { // the number of remaining keepalive slots is less than or equal to the threshold. private final int mReservedPrivilegedSlots; + // Allowed unprivileged keepalive slots per uid. Caller's permission will be enforced if + // the number of remaining keepalive slots is less than or equal to the threshold. + private final int mAllowedUnprivilegedSlotsForUid; + public KeepaliveTracker(Context context, Handler handler) { mConnectivityServiceHandler = handler; mTcpController = new TcpKeepaliveController(handler); @@ -111,6 +115,8 @@ public class KeepaliveTracker { mSupportedKeepalives = KeepaliveUtils.getSupportedKeepalives(mContext); mReservedPrivilegedSlots = mContext.getResources().getInteger( R.integer.config_reservedPrivilegedKeepaliveSlots); + mAllowedUnprivilegedSlotsForUid = mContext.getResources().getInteger( + R.integer.config_allowedUnprivilegedKeepalivePerUid); } /** @@ -275,6 +281,18 @@ public class KeepaliveTracker { return ERROR_INSUFFICIENT_RESOURCES; } + // Count unprivileged keepalives for the same uid across networks. + int unprivilegedCountSameUid = 0; + for (final HashMap kaForNetwork : mKeepalives.values()) { + for (final KeepaliveInfo ki : kaForNetwork.values()) { + if (ki.mUid == mUid) { + unprivilegedCountSameUid++; + } + } + } + if (unprivilegedCountSameUid > mAllowedUnprivilegedSlotsForUid) { + return ERROR_INSUFFICIENT_RESOURCES; + } return SUCCESS; } @@ -674,6 +692,7 @@ public class KeepaliveTracker { public void dump(IndentingPrintWriter pw) { pw.println("Supported Socket keepalives: " + Arrays.toString(mSupportedKeepalives)); pw.println("Reserved Privileged keepalives: " + mReservedPrivilegedSlots); + pw.println("Allowed Unprivileged keepalives per uid: " + mAllowedUnprivilegedSlotsForUid); pw.println("Socket keepalives:"); pw.increaseIndent(); for (NetworkAgentInfo nai : mKeepalives.keySet()) {