From d6c614f7785857b8b29e825f883d27c1406ad699 Mon Sep 17 00:00:00 2001 From: junyulai Date: Fri, 28 Aug 2020 13:44:33 +0800 Subject: 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 --- .../com/android/server/ConnectivityService.java | 21 +++++++++++++++++++++ .../com/android/server/net/LockdownVpnTracker.java | 22 +++++++--------------- 2 files changed, 28 insertions(+), 15 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index ecb935edde21..ec6a451324fa 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -16,6 +16,7 @@ package com.android.server; +import static android.Manifest.permission.NETWORK_STACK; import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityDiagnosticsManager.ConnectivityReport.KEY_NETWORK_PROBES_ATTEMPTED_BITMASK; @@ -1136,6 +1137,12 @@ public class ConnectivityService extends IConnectivityManager.Stub null /* broadcastPermission */, 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 { mNMS.registerObserver(mDataActivityObserver); } 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() { @Override public void onReceive(Context context, Intent intent) { @@ -5205,6 +5218,12 @@ public class ConnectivityService extends IConnectivityManager.Stub final Uri packageData = intent.getData(); final String packageName = 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 (Intent.ACTION_USER_STARTED.equals(action)) { @@ -5223,6 +5242,8 @@ public class ConnectivityService extends IConnectivityManager.Stub final boolean isReplacing = intent.getBooleanExtra( Intent.EXTRA_REPLACING, false); onPackageRemoved(packageName, uid, isReplacing); + } else { + Log.wtf(TAG, "received unexpected intent: " + action); } } }; diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java index 3cafafffc62a..05f280884432 100644 --- a/services/core/java/com/android/server/net/LockdownVpnTracker.java +++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java @@ -16,7 +16,6 @@ package com.android.server.net; -import static android.Manifest.permission.NETWORK_STACK; import static android.provider.Settings.ACTION_VPN_SETTINGS; import android.annotation.NonNull; @@ -24,10 +23,8 @@ import android.annotation.Nullable; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.LinkAddress; import android.net.LinkProperties; @@ -41,6 +38,7 @@ import android.text.TextUtils; import android.util.Slog; import com.android.internal.R; +import com.android.internal.annotations.GuardedBy; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.net.VpnConfig; import com.android.internal.net.VpnProfile; @@ -63,7 +61,7 @@ public class LockdownVpnTracker { /** Number of VPN attempts before waiting for user intervention. */ private static final int MAX_ERROR_COUNT = 4; - private static final String ACTION_LOCKDOWN_RESET = "com.android.server.action.LOCKDOWN_RESET"; + public static final String ACTION_LOCKDOWN_RESET = "com.android.server.action.LOCKDOWN_RESET"; @NonNull private final Context mContext; @NonNull private final ConnectivityService mConnService; @@ -104,13 +102,6 @@ public class LockdownVpnTracker { mResetIntent = PendingIntent.getBroadcast(mContext, 0, resetIntent, 0); } - private BroadcastReceiver mResetReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - reset(); - } - }; - /** * Watch for state changes to both active egress network, kicking off a VPN * connection when ready, or setting firewall rules once VPN is connected. @@ -200,9 +191,6 @@ public class LockdownVpnTracker { mVpn.setEnableTeardown(false); mVpn.setLockdown(true); - - final IntentFilter resetFilter = new IntentFilter(ACTION_LOCKDOWN_RESET); - mContext.registerReceiver(mResetReceiver, resetFilter, NETWORK_STACK, mHandler); handleStateChangedLocked(); } @@ -222,10 +210,14 @@ public class LockdownVpnTracker { mVpn.setLockdown(false); hideNotification(); - mContext.unregisterReceiver(mResetReceiver); mVpn.setEnableTeardown(true); } + /** + * Reset VPN lockdown tracker. Called by ConnectivityService when receiving + * {@link #ACTION_LOCKDOWN_RESET} pending intent. + */ + @GuardedBy("mConnService.mVpns") public void reset() { Slog.d(TAG, "reset()"); synchronized (mStateLock) { -- cgit v1.2.3-59-g8ed1b