Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d6c614f7 authored by junyulai's avatar junyulai
Browse files

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
parent 90b0d3f8
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -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);
            }
        }
    };
+7 −15
Original line number Diff line number Diff line
@@ -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) {