Check NetworkAgentInfo Map Before Destroying Network
updateNetworkInfo is called with the argument in a message,
which is initialized with `this` in NetworkAgentRegistry.
That means it's technically possible that CS calls
tearDownUnneededNetwork, calling nai.disconnect() and
queuing up a message to call this, but before it's done
the NA calls sendNetworkInfo with DISCONNECTED, which
never looks up the agent from the map. Throwing a
ServiceSpecificException and resulting in a System crash.
Bug: 196423147
Change-Id: Ia52f2b794f32c263200c14b8dc2eb6b184bff5ff
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 34e15ca..d9fe428 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -3844,9 +3844,7 @@
private void handleNetworkAgentDisconnected(Message msg) {
NetworkAgentInfo nai = (NetworkAgentInfo) msg.obj;
- if (mNetworkAgentInfos.contains(nai)) {
- disconnectAndDestroyNetwork(nai);
- }
+ disconnectAndDestroyNetwork(nai);
}
// Destroys a network, remove references to it from the internal state managed by
@@ -3854,6 +3852,9 @@
// Must be called on the Handler thread.
private void disconnectAndDestroyNetwork(NetworkAgentInfo nai) {
ensureRunningOnConnectivityServiceThread();
+
+ if (!mNetworkAgentInfos.contains(nai)) return;
+
if (DBG) {
log(nai.toShortString() + " disconnected, was satisfying " + nai.numNetworkRequests());
}
@@ -3939,7 +3940,7 @@
try {
mNetd.networkSetPermissionForNetwork(nai.network.netId, INetd.PERMISSION_SYSTEM);
} catch (RemoteException e) {
- Log.d(TAG, "Error marking network restricted during teardown: " + e);
+ Log.d(TAG, "Error marking network restricted during teardown: ", e);
}
mHandler.postDelayed(() -> destroyNetwork(nai), nai.teardownDelayMs);
}