Don't crash ConnectivityService if the network stack crashes.

When the network stack crashes, the system will rebind to it.
Existing references are no longer useful (they just throw
RemoteException) but if the system is still up, then the user
can at least recover the situation by taking actions such as
going into airplane mode, toggling wifi, etc.

This CL stops ConnectivityService from crashing the system when
it cannot talk to NetworkMonitor. This is arguably better than
crashing the system, because crashing the system is disruptive
and carries the serious risk of a bootloop from which it is not
possible to recover.

NetworkStackClient already contains code to crash the system
when the network stack crashes. This change help ensure that
if a crash occurs, it is the result of an explicit decision by
that code instead of an unchecked exception in one of the callers
of the network stack.

Bug: 133725814
Test: builds, boots
Test: atest FrameworksNetTests NetworkStackTests
Change-Id: Ib9a15fececd8579fc5b139fe0341275a45512e0f
This commit is contained in:
Lorenzo Colitti
2019-05-31 15:41:29 +09:00
parent 635b441ff9
commit 6edf86cd9c
2 changed files with 22 additions and 61 deletions

View File

@@ -91,6 +91,7 @@ import android.net.NetworkFactory;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkMisc;
import android.net.NetworkMonitorManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
@@ -1784,8 +1785,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// callback from each caller type. Need to re-factor NetdEventListenerService to allow
// multiple NetworkMonitor registrants.
if (nai != null && nai.satisfies(mDefaultRequest)) {
Binder.withCleanCallingIdentity(() ->
nai.networkMonitor().notifyDnsResponse(returnCode));
nai.networkMonitor().notifyDnsResponse(returnCode);
}
}
@@ -2852,11 +2852,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Notify the NetworkAgentInfo/NetworkMonitor in case NetworkMonitor needs to cancel or
// schedule DNS resolutions. If a DNS resolution is required the
// result will be sent back to us.
try {
nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
nai.networkMonitor().notifyPrivateDnsChanged(cfg.toParcel());
// With Private DNS bypass support, we can proceed to update the
// Private DNS config immediately, even if we're in strict mode
@@ -3022,11 +3018,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Disable wakeup packet monitoring for each interface.
wakeupModifyInterface(iface, nai.networkCapabilities, false);
}
try {
nai.networkMonitor().notifyNetworkDisconnected();
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
nai.networkMonitor().notifyNetworkDisconnected();
mNetworkAgentInfos.remove(nai.messenger);
nai.clatd.update();
synchronized (mNetworkForNetId) {
@@ -3439,11 +3431,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
//
// TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
// per network. Therefore, NetworkMonitor may still do https probe.
try {
nai.networkMonitor().setAcceptPartialConnectivity();
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
nai.networkMonitor().setAcceptPartialConnectivity();
}
}
@@ -3475,11 +3463,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai == null) return;
if (!nai.networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) return;
try {
nai.networkMonitor().launchCaptivePortalApp();
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
nai.networkMonitor().launchCaptivePortalApp();
});
}
@@ -3514,7 +3498,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
@Override
public void appResponse(final int response) throws RemoteException {
public void appResponse(final int response) {
if (response == CaptivePortal.APP_RETURN_WANTED_AS_IS) {
enforceSettingsPermission();
}
@@ -3524,16 +3508,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (nai == null) return;
// nai.networkMonitor() is thread-safe
final INetworkMonitor nm = nai.networkMonitor();
final NetworkMonitorManager nm = nai.networkMonitor();
if (nm == null) return;
final long token = Binder.clearCallingIdentity();
try {
nm.notifyCaptivePortalAppFinished(response);
} finally {
// Not using Binder.withCleanCallingIdentity() to keep the checked RemoteException
Binder.restoreCallingIdentity(token);
}
nm.notifyCaptivePortalAppFinished(response);
}
@Override
@@ -4104,11 +4081,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (isNetworkWithLinkPropertiesBlocked(lp, uid, false)) {
return;
}
try {
nai.networkMonitor().forceReevaluation(uid);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
nai.networkMonitor().forceReevaluation(uid);
}
/**
@@ -5541,11 +5514,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// Start or stop DNS64 detection and 464xlat according to network state.
networkAgent.clatd.update();
notifyIfacesChangedForNetworkStats();
try {
networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
networkAgent.networkMonitor().notifyLinkPropertiesChanged(newLp);
if (networkAgent.everConnected) {
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_IP_CHANGED);
}
@@ -6529,15 +6498,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
// command must be sent after updating LinkProperties to maximize chances of
// NetworkMonitor seeing the correct LinkProperties when starting.
// TODO: pass LinkProperties to the NetworkMonitor in the notifyNetworkConnected call.
try {
if (networkAgent.networkMisc.acceptPartialConnectivity) {
networkAgent.networkMonitor().setAcceptPartialConnectivity();
}
networkAgent.networkMonitor().notifyNetworkConnected(
networkAgent.linkProperties, networkAgent.networkCapabilities);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
if (networkAgent.networkMisc.acceptPartialConnectivity) {
networkAgent.networkMonitor().setAcceptPartialConnectivity();
}
networkAgent.networkMonitor().notifyNetworkConnected(
networkAgent.linkProperties, networkAgent.networkCapabilities);
scheduleUnvalidatedPrompt(networkAgent);
// Whether a particular NetworkRequest listen should cause signal strength thresholds to

View File

@@ -25,12 +25,12 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkMisc;
import android.net.NetworkMonitorManager;
import android.net.NetworkRequest;
import android.net.NetworkState;
import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.Messenger;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray;
@@ -247,7 +247,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
public final Nat464Xlat clatd;
// Set after asynchronous creation of the NetworkMonitor.
private volatile INetworkMonitor mNetworkMonitor;
private volatile NetworkMonitorManager mNetworkMonitor;
private static final String TAG = ConnectivityService.class.getSimpleName();
private static final boolean VDBG = false;
@@ -278,7 +278,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
* Inform NetworkAgentInfo that a new NetworkMonitor was created.
*/
public void onNetworkMonitorCreated(INetworkMonitor networkMonitor) {
mNetworkMonitor = networkMonitor;
mNetworkMonitor = new NetworkMonitorManager(networkMonitor);
}
/**
@@ -290,13 +290,9 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
*/
public void setNetworkCapabilities(NetworkCapabilities nc) {
networkCapabilities = nc;
final INetworkMonitor nm = mNetworkMonitor;
final NetworkMonitorManager nm = mNetworkMonitor;
if (nm != null) {
try {
nm.notifyNetworkCapabilitiesChanged(nc);
} catch (RemoteException e) {
Log.e(TAG, "Error notifying NetworkMonitor of updated NetworkCapabilities", e);
}
nm.notifyNetworkCapabilitiesChanged(nc);
}
}
@@ -317,11 +313,11 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
}
/**
* Get the INetworkMonitor in this NetworkAgentInfo.
* Get the NetworkMonitorManager in this NetworkAgentInfo.
*
* <p>This will be null before {@link #onNetworkMonitorCreated(INetworkMonitor)} is called.
*/
public INetworkMonitor networkMonitor() {
public NetworkMonitorManager networkMonitor() {
return mNetworkMonitor;
}