Handle lockdown VPN reset intent in ConnectivityService

Currently, LockdownVpnTracker handles lockdown VPN reset intent.
Which will grab VPN object as a lock, then calls into
ConnectivityService to grab mVpn lock when querying NetworkInfo.
However, the order of grabing locks differs from ConnectivityService
and will causes deadlock if ConnectivityService grabs locks in
the other order.

Thus, make ConnectivityService handles reset intent so the
order of grabing locks can be consistent.

Test: atest FrameworksNetTests
Bug: 147403549
Change-Id: Ia10a3ef6f1e20d092a17313935083a84860961aa
This commit is contained in:
junyulai
2020-08-28 13:44:33 +08:00
parent c4aaac8af6
commit d91e70589d

View File

@@ -16,6 +16,7 @@
package com.android.server; package com.android.server;
import static android.Manifest.permission.NETWORK_STACK;
import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK; import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK;
@@ -1136,6 +1137,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
null /* broadcastPermission */, null /* broadcastPermission */,
mHandler); mHandler);
// Listen to lockdown VPN reset.
intentFilter = new IntentFilter();
intentFilter.addAction(LockdownVpnTracker.ACTION_LOCKDOWN_RESET);
mContext.registerReceiverAsUser(
mIntentReceiver, UserHandle.ALL, intentFilter, NETWORK_STACK, mHandler);
try { try {
mNMS.registerObserver(mDataActivityObserver); mNMS.registerObserver(mDataActivityObserver);
} catch (RemoteException e) { } catch (RemoteException e) {
@@ -5195,6 +5202,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
} }
} }
private void onVpnLockdownReset() {
synchronized (mVpns) {
if (mLockdownTracker != null) mLockdownTracker.reset();
}
}
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@@ -5205,6 +5218,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
final Uri packageData = intent.getData(); final Uri packageData = intent.getData();
final String packageName = final String packageName =
packageData != null ? packageData.getSchemeSpecificPart() : null; packageData != null ? packageData.getSchemeSpecificPart() : null;
if (LockdownVpnTracker.ACTION_LOCKDOWN_RESET.equals(action)) {
onVpnLockdownReset();
}
// UserId should be filled for below intents, check the existence.
if (userId == UserHandle.USER_NULL) return; if (userId == UserHandle.USER_NULL) return;
if (Intent.ACTION_USER_STARTED.equals(action)) { if (Intent.ACTION_USER_STARTED.equals(action)) {
@@ -5223,6 +5242,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
final boolean isReplacing = intent.getBooleanExtra( final boolean isReplacing = intent.getBooleanExtra(
Intent.EXTRA_REPLACING, false); Intent.EXTRA_REPLACING, false);
onPackageRemoved(packageName, uid, isReplacing); onPackageRemoved(packageName, uid, isReplacing);
} else {
Log.wtf(TAG, "received unexpected intent: " + action);
} }
} }
}; };