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

Commit 319c2e5a authored by Hugh Chen's avatar Hugh Chen Committed by Kevin Haggerty
Browse files

RESTRICT AUTOMERGE Fix bluetooth settings will broadcast to anywhere when some cases



BluetoothPermissionActivity and DevicePickerFragment will send
broadcast to return the result to calling apps. As this broadcast
intent is from Settings with uid 1000, it will be sent to any
protected BroadcastReceivers in the device. It can make an attacker
send broadcast to protected BroadcastReceivers like factory reset intent
(android/com.android.server.MasterClearReceiver) via
BluetoothPermissionActivity or DevicePickerFragment.

This CL will not allow to set package name and class name to avoid
the attacker.

Bug: 179386960
Bug: 179386068
Test: make -j42 RunSettingsRoboTests and use test apk to manually test
to verify factory reset not started and no system UI notification.

[basilgello: Backport to 14.1]
Signed-off-by: default avatarVasyl Gello <vasek.gello@gmail.com>

Change-Id: Id27a78091ab578077853b8fbb97a4422cff0a158
(cherry picked from commit 8adedc62)
(cherry picked from commit c2adcb2d)
parent 995e7be0
Loading
Loading
Loading
Loading
+8 −11
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.settings.bluetooth;

import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;

import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -30,6 +32,7 @@ import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.AlertActivity;
import com.android.internal.app.AlertController;
import com.android.settings.R;
@@ -37,8 +40,6 @@ import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;

import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;

/**
 * BluetoothPermissionActivity shows a dialog for accepting incoming
 * profile connection request from untrusted devices.
@@ -54,8 +55,6 @@ public class BluetoothPermissionActivity extends AlertActivity implements
    private TextView messageView;
    private Button mOkButton;
    private BluetoothDevice mDevice;
    private String mReturnPackage = null;
    private String mReturnClass = null;

    private int mRequestType = 0;
    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@@ -92,8 +91,6 @@ public class BluetoothPermissionActivity extends AlertActivity implements
        }

        mDevice = i.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        mReturnPackage = i.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME);
        mReturnClass = i.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME);
        mRequestType = i.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
                                     BluetoothDevice.REQUEST_TYPE_PHONEBOOK_ACCESS);

@@ -231,14 +228,14 @@ public class BluetoothPermissionActivity extends AlertActivity implements
        sendReplyIntentToReceiver(false, always);
    }

    private void sendReplyIntentToReceiver(final boolean allowed, final boolean always) {
    @VisibleForTesting
    void sendReplyIntentToReceiver(final boolean allowed, final boolean always) {
        Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);

        if (mReturnPackage != null && mReturnClass != null) {
            intent.setClassName(mReturnPackage, mReturnClass);
        if (DEBUG) {
            Log.i(TAG, "sendReplyIntentToReceiver() Request type: " + mRequestType
                    + " mReturnPackage");
        }
        if (DEBUG) Log.i(TAG, "sendReplyIntentToReceiver() Request type: " + mRequestType +
                " mReturnPackage" + mReturnPackage + " mReturnClass" + mReturnClass);

        intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                        allowed ? BluetoothDevice.CONNECTION_ACCESS_YES
+6 −15
Original line number Diff line number Diff line
@@ -49,8 +49,6 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver {
    Context mContext;
    int mRequestType;
    BluetoothDevice mDevice;
    String mReturnPackage = null;
    String mReturnClass = null;

    @Override
    public void onReceive(Context context, Intent intent) {
@@ -70,11 +68,10 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver {
            mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            mRequestType = intent.getIntExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
                                                 BluetoothDevice.REQUEST_TYPE_PROFILE_CONNECTION);
            mReturnPackage = intent.getStringExtra(BluetoothDevice.EXTRA_PACKAGE_NAME);
            mReturnClass = intent.getStringExtra(BluetoothDevice.EXTRA_CLASS_NAME);

            if (DEBUG) Log.d(TAG, "onReceive request type: " + mRequestType + " return "
                    + mReturnPackage + "," + mReturnClass);
            if (DEBUG) {
                Log.d(TAG, "onReceive request type: " + mRequestType);
            }

            // Even if the user has already made the choice, Bluetooth still may not know that if
            // the user preference data have not been migrated from Settings app's shared
@@ -103,8 +100,6 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver {
            connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_ACCESS_REQUEST_TYPE,
                                            mRequestType);
            connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
            connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_PACKAGE_NAME, mReturnPackage);
            connectionAccessIntent.putExtra(BluetoothDevice.EXTRA_CLASS_NAME, mReturnClass);

            String deviceAddress = mDevice != null ? mDevice.getAddress() : null;
            String deviceName = mDevice != null ? mDevice.getName() : null;
@@ -283,10 +278,6 @@ public final class BluetoothPermissionRequest extends BroadcastReceiver {
    private void sendReplyIntentToReceiver(final boolean allowed) {
        Intent intent = new Intent(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY);

        if (mReturnPackage != null && mReturnClass != null) {
            intent.setClassName(mReturnPackage, mReturnClass);
        }

        intent.putExtra(BluetoothDevice.EXTRA_CONNECTION_ACCESS_RESULT,
                allowed ? BluetoothDevice.CONNECTION_ACCESS_YES
                        : BluetoothDevice.CONNECTION_ACCESS_NO);
+11 −10
Original line number Diff line number Diff line
@@ -16,6 +16,10 @@

package com.android.settings.bluetooth;

import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;
import com.android.internal.annotations.VisibleForTesting;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDevicePicker;
@@ -31,22 +35,22 @@ import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;

import static android.os.UserManager.DISALLOW_CONFIG_BLUETOOTH;

/**
 * BluetoothSettings is the Settings screen for Bluetooth configuration and
 * connection management.
 */
public final class DevicePickerFragment extends DeviceListPreferenceFragment {
    private static final int MENU_ID_REFRESH = Menu.FIRST;
    private static final String TAG = "DevicePickerFragment";

    public DevicePickerFragment() {
        super(null /* Not tied to any user restrictions. */);
    }

    @VisibleForTesting
    Context mContext;

    private boolean mNeedAuth;
    private String mLaunchPackage;
    private String mLaunchClass;
    private boolean mStartScanOnResume;
    private boolean mDeviceSelected;

@@ -58,8 +62,6 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment {
        mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
        setFilter(intent.getIntExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE,
                BluetoothDevicePicker.FILTER_TYPE_ALL));
        mLaunchPackage = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE);
        mLaunchClass = intent.getStringExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS);
    }

    @Override
@@ -97,6 +99,7 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment {
        UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
        mStartScanOnResume = !um.hasUserRestriction(DISALLOW_CONFIG_BLUETOOTH)
                && (savedInstanceState == null);  // don't start scan after rotation
        mContext = getContext();
        setHasOptionsMenu(true);
    }

@@ -164,9 +167,7 @@ public final class DevicePickerFragment extends DeviceListPreferenceFragment {
        mDeviceSelected = true;
        Intent intent = new Intent(BluetoothDevicePicker.ACTION_DEVICE_SELECTED);
        intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
        if (mLaunchPackage != null && mLaunchClass != null) {
            intent.setClassName(mLaunchPackage, mLaunchClass);
        }
        getActivity().sendBroadcast(intent);

        mContext.sendBroadcast(intent, Manifest.permission.BLUETOOTH_ADMIN);
    }
}