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

Commit b5922c05 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Ensure privileged APIs require runtime permission.

When users revoke a runtime permission, they expect all interactions
to be blocked, including those protected by the BLUETOOTH_PRIVILEGED
permission.

This change finishes applying that policy to any remaining Bluetooth
APIs which didn't already implement it.  To keep the implementation
straightforward, this change does "data delivery" checks when
registering for callbacks; the ideal behavior would be to wait
until data is actually delivered through the callbacks, but
RemoteCallbackList doesn't have support for AttributionSource yet.

Bug: 186405452
Test: atest BluetoothInstrumentationTests
Change-Id: Ibeb1889da6109e3e2ab567970aac49f4e34df1dc
parent 3d7a7b66
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.bluetooth;

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

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -33,6 +34,7 @@ import android.view.accessibility.AccessibilityEvent;
 * @see #mAlert
 * @see #setupAlert()
 */
@SuppressLint("AndroidFrameworkBluetoothPermission")
public abstract class AlertActivity extends Activity implements DialogInterface.OnDismissListener,
        DialogInterface.OnCancelListener {

+123 −81

File changed.

Preview size limit exceeded, changes collapsed.

+11 −4
Original line number Diff line number Diff line
@@ -943,12 +943,12 @@ public class GattService extends ProfileService {
        }

        @Override
        public void getOwnAddress(int advertiserId) {
        public void getOwnAddress(int advertiserId, AttributionSource attributionSource) {
            GattService service = getService();
            if (service == null) {
                return;
            }
            service.getOwnAddress(advertiserId);
            service.getOwnAddress(advertiserId, attributionSource);
        }

        @Override
@@ -2522,8 +2522,15 @@ public class GattService extends ProfileService {
        mAdvertiseManager.stopAdvertisingSet(callback);
    }

    @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
    void getOwnAddress(int advertiserId) {
    @RequiresPermission(allOf = {
            android.Manifest.permission.BLUETOOTH_ADVERTISE,
            android.Manifest.permission.BLUETOOTH_PRIVILEGED,
    })
    void getOwnAddress(int advertiserId, AttributionSource attributionSource) {
        if (!Utils.checkAdvertisePermissionForDataDelivery(
                this, attributionSource, "GattService getOwnAddress")) {
            return;
        }
        enforcePrivilegedPermission();
        mAdvertiseManager.getOwnAddress(advertiserId);
    }
+9 −9
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ public class AdapterServiceTest {
        mAdapterService.attach(mMockContext, null, null, null, mApplication, null);

        mAdapterService.onCreate();
        mServiceBinder.registerCallback(mIBluetoothCallback);
        mServiceBinder.registerCallback(mIBluetoothCallback, mAttributionSource);

        Config.init(mMockContext);

@@ -194,7 +194,7 @@ public class AdapterServiceTest {

    @After
    public void tearDown() {
        mServiceBinder.unregisterCallback(mIBluetoothCallback);
        mServiceBinder.unregisterCallback(mIBluetoothCallback, mAttributionSource);
        mAdapterService.cleanup();
        Config.init(InstrumentationRegistry.getTargetContext());
    }
@@ -227,7 +227,7 @@ public class AdapterServiceTest {
        verifyStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON, BluetoothAdapter.STATE_BLE_ON,
                invocationNumber + 1, NATIVE_INIT_MS);

        mServiceBinder.onLeServiceUp();
        mServiceBinder.onLeServiceUp(mAttributionSource);

        verifyStateChange(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_TURNING_ON,
                invocationNumber + 1, CONTEXT_SWITCH_MS);
@@ -275,7 +275,7 @@ public class AdapterServiceTest {
        verifyStateChange(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_BLE_ON,
                invocationNumber + 1, PROFILE_SERVICE_TOGGLE_TIME_MS);

        mServiceBinder.onBrEdrDown();
        mServiceBinder.onBrEdrDown(mAttributionSource);

        verifyStateChange(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_BLE_TURNING_OFF,
                invocationNumber + 1, CONTEXT_SWITCH_MS);
@@ -389,7 +389,7 @@ public class AdapterServiceTest {
        verifyStateChange(BluetoothAdapter.STATE_TURNING_OFF, BluetoothAdapter.STATE_BLE_ON, 1,
                CONTEXT_SWITCH_MS);

        mServiceBinder.onBrEdrDown();
        mServiceBinder.onBrEdrDown(mAttributionSource);

        verifyStateChange(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_BLE_TURNING_OFF, 1,
                CONTEXT_SWITCH_MS);
@@ -424,7 +424,7 @@ public class AdapterServiceTest {
        verifyStateChange(BluetoothAdapter.STATE_BLE_TURNING_ON, BluetoothAdapter.STATE_BLE_ON, 1,
                NATIVE_INIT_MS);

        mServiceBinder.onLeServiceUp();
        mServiceBinder.onLeServiceUp(mAttributionSource);

        verifyStateChange(BluetoothAdapter.STATE_BLE_ON, BluetoothAdapter.STATE_TURNING_ON, 1,
                CONTEXT_SWITCH_MS);
@@ -656,7 +656,7 @@ public class AdapterServiceTest {
        byte[] obfuscatedAddress1 = mAdapterService.obfuscateAddress(device);
        Assert.assertTrue(obfuscatedAddress1.length > 0);
        Assert.assertFalse(isByteArrayAllZero(obfuscatedAddress1));
        mServiceBinder.factoryReset();
        mServiceBinder.factoryReset(mAttributionSource);
        byte[] obfuscatedAddress2 = mAdapterService.obfuscateAddress(device);
        Assert.assertTrue(obfuscatedAddress2.length > 0);
        Assert.assertFalse(isByteArrayAllZero(obfuscatedAddress2));
@@ -668,7 +668,7 @@ public class AdapterServiceTest {
        Assert.assertFalse(isByteArrayAllZero(obfuscatedAddress3));
        Assert.assertArrayEquals(obfuscatedAddress3,
                obfuscatedAddress2);
        mServiceBinder.factoryReset();
        mServiceBinder.factoryReset(mAttributionSource);
        byte[] obfuscatedAddress4 = mAdapterService.obfuscateAddress(device);
        Assert.assertTrue(obfuscatedAddress4.length > 0);
        Assert.assertFalse(isByteArrayAllZero(obfuscatedAddress4));
@@ -692,7 +692,7 @@ public class AdapterServiceTest {
        Assert.assertFalse(isByteArrayAllZero(obfuscatedAddress1));
        Assert.assertArrayEquals(obfuscateInJava(metricsSalt1, device),
                obfuscatedAddress1);
        mServiceBinder.factoryReset();
        mServiceBinder.factoryReset(mAttributionSource);
        tearDown();
        setUp();
        // Cannot verify metrics salt since it is not written to disk until native cleanup