From 73ed9d8dee5ef7139b84c8e1713fec7ff5ccce5d Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 19 Aug 2014 18:58:04 -0700 Subject: [PATCH] Fix CS/NetworkMonitor race. If we have a message in flight about a NetworkAgentInfo when it gets disconnected we are left with a zombie network. Fixes this by verifing the network is still live before we process the msg. bug:17142206 Change-Id: I2c94a39b3ea97c1562066571b277280c1f69f71c --- .../com/android/server/ConnectivityService.java | 34 +++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 5bef4bf2272a..b04773a34f06 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1733,6 +1733,19 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } + private boolean isLiveNetworkAgent(NetworkAgentInfo nai, String msg) { + final NetworkAgentInfo officialNai; + synchronized (mNetworkForNetId) { + officialNai = mNetworkForNetId.get(nai.network.netId); + } + if (officialNai != null && officialNai.equals(nai)) return true; + if (officialNai != null || VDBG) { + loge(msg + " - validateNetworkAgent found mismatched netId: " + officialNai + + " - " + nai); + } + return false; + } + // must be stateless - things change under us. private class NetworkStateTrackerHandler extends Handler { public NetworkStateTrackerHandler(Looper looper) { @@ -1862,23 +1875,30 @@ public class ConnectivityService extends IConnectivityManager.Stub { } case NetworkMonitor.EVENT_NETWORK_VALIDATED: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; - handleConnectionValidated(nai); + if (isLiveNetworkAgent(nai, "EVENT_NETWORK_VALIDATED")) { + handleConnectionValidated(nai); + } break; } case NetworkMonitor.EVENT_NETWORK_LINGER_COMPLETE: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; - handleLingerComplete(nai); + if (isLiveNetworkAgent(nai, "EVENT_NETWORK_LINGER_COMPLETE")) { + handleLingerComplete(nai); + } break; } case NetworkMonitor.EVENT_PROVISIONING_NOTIFICATION: { + NetworkAgentInfo nai = null; + synchronized (mNetworkForNetId) { + nai = mNetworkForNetId.get(msg.arg2); + } + if (nai == null) { + loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); + break; + } if (msg.arg1 == 0) { setProvNotificationVisibleIntent(false, msg.arg2, 0, null, null); } else { - NetworkAgentInfo nai = mNetworkForNetId.get(msg.arg2); - if (nai == null) { - loge("EVENT_PROVISIONING_NOTIFICATION from unknown NetworkMonitor"); - break; - } setProvNotificationVisibleIntent(true, msg.arg2, nai.networkInfo.getType(), nai.networkInfo.getExtraInfo(), (PendingIntent)msg.obj); } -- 2.11.0