From 06ec50d68354a00f3f3e0e55fe42e9d13b6fbba6 Mon Sep 17 00:00:00 2001 From: Zhengyu Zhan Date: Mon, 10 Aug 2020 11:25:14 +0800 Subject: [PATCH] Fix NetworkPolicyManagerService deadlock When NetworkPolicyManagerService binder call Phone process while holding a lock, the lock will block Applications binder call, then system_server's binder will exhaust, may cause dead lock. The solution is don't call phone process while holding a lock. Bug: 146537388 Test: com.android.server.net.NetworkPolicyManagerServiceTest com.android.cts.net.HostsideRestrictBackgroundNetworkTests Change-Id: I57aac7f8f5c115ce68a69f84286c58c80c22fb55 --- .../net/NetworkPolicyManagerService.java | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java index 7d0457bdaec4f..e8f48262fbbf9 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java @@ -559,6 +559,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** Set of all merged subscriberId as of last update */ @GuardedBy("mNetworkPoliciesSecondLock") private List mMergedSubscriberIds = new ArrayList<>(); + /** Map from subId to carrierConfig as of last update */ + @GuardedBy("mNetworkPoliciesSecondLock") + private final SparseArray mSubIdToCarrierConfig = + new SparseArray(); /** * Indicates the uids restricted by admin from accessing metered data. It's a mapping from @@ -1186,7 +1190,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final long totalBytes = getTotalBytes(policy.template, cycleStart, cycleEnd); // Carrier might want to manage notifications themselves - final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); + final PersistableBundle config = mSubIdToCarrierConfig.get(subId); if (!CarrierConfigManager.isConfigForIdentifiedCarrier(config)) { if (LOGV) Slog.v(TAG, "isConfigForIdentifiedCarrier returned false"); // Don't show notifications until we confirm that the loaded config is from an @@ -1831,8 +1835,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final List mergedSubscriberIdsList = new ArrayList(); final SparseArray subIdToSubscriberId = new SparseArray<>(subList.size()); + final SparseArray subIdToCarrierConfig = + new SparseArray(); for (final SubscriptionInfo sub : subList) { - final TelephonyManager tmSub = tm.createForSubscriptionId(sub.getSubscriptionId()); + final int subId = sub.getSubscriptionId(); + final TelephonyManager tmSub = tm.createForSubscriptionId(subId); final String subscriberId = tmSub.getSubscriberId(); if (!TextUtils.isEmpty(subscriberId)) { subIdToSubscriberId.put(tmSub.getSubscriptionId(), subscriberId); @@ -1843,6 +1850,13 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { final String[] mergedSubscriberId = ArrayUtils.defeatNullable( tmSub.getMergedImsisFromGroup()); mergedSubscriberIdsList.add(mergedSubscriberId); + + final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); + if (config != null) { + subIdToCarrierConfig.put(subId, config); + } else { + Slog.e(TAG, "Missing CarrierConfig for subId " + subId); + } } synchronized (mNetworkPoliciesSecondLock) { @@ -1853,6 +1867,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } mMergedSubscriberIds = mergedSubscriberIdsList; + + mSubIdToCarrierConfig.clear(); + for (int i = 0; i < subIdToCarrierConfig.size(); i++) { + mSubIdToCarrierConfig.put(subIdToCarrierConfig.keyAt(i), + subIdToCarrierConfig.valueAt(i)); + } } Trace.traceEnd(TRACE_TAG_NETWORK); @@ -2172,7 +2192,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } else { - final PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId); + final PersistableBundle config = mSubIdToCarrierConfig.get(subId); final int currentCycleDay; if (policy.cycleRule.isMonthly()) { currentCycleDay = policy.cycleRule.start.getDayOfMonth();