Restrict AdbManager broadcasts to apps with MANAGE_DEBUGGING permission.

Bug: 205836329
Test: atest AdbDebuggingManagerTest
Change-Id: If18a874c6d6232d9131f2cc3de3614ef67a58bbd
(cherry picked from commit b139e99661)
This commit is contained in:
Joshua Duong
2021-12-22 14:49:21 -08:00
parent e088b3cb5a
commit 398b752a44
4 changed files with 129 additions and 7 deletions

View File

@@ -38,6 +38,7 @@ public class AdbManager {
*
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING)
public static final String WIRELESS_DEBUG_STATE_CHANGED_ACTION =
"com.android.server.adb.WIRELESS_DEBUG_STATUS";
@@ -46,6 +47,7 @@ public class AdbManager {
*
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING)
public static final String WIRELESS_DEBUG_PAIRED_DEVICES_ACTION =
"com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES";
@@ -59,6 +61,7 @@ public class AdbManager {
*
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DEBUGGING)
public static final String WIRELESS_DEBUG_PAIRING_RESULT_ACTION =
"com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT";

View File

@@ -18,6 +18,7 @@ package com.android.server.adb;
import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull;
import android.annotation.NonNull;
import android.annotation.TestApi;
import android.app.ActivityManager;
import android.app.Notification;
@@ -171,6 +172,12 @@ public class AdbDebuggingManager {
mAdbConnectionInfo = new AdbConnectionInfo();
}
static void sendBroadcastWithDebugPermission(@NonNull Context context, @NonNull Intent intent,
@NonNull UserHandle userHandle) {
context.sendBroadcastAsUser(intent, userHandle,
android.Manifest.permission.MANAGE_DEBUGGING);
}
class PairingThread extends Thread implements NsdManager.RegistrationListener {
private NsdManager mNsdManager;
private String mPublicKey;
@@ -1279,7 +1286,7 @@ public class AdbDebuggingManager {
? AdbManager.WIRELESS_STATUS_CONNECTED
: AdbManager.WIRELESS_STATUS_DISCONNECTED);
intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL);
}
private void onAdbdWifiServerConnected(int port) {
@@ -1351,7 +1358,8 @@ public class AdbDebuggingManager {
if (publicKey == null) {
Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION);
intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, AdbManager.WIRELESS_STATUS_FAIL);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent,
UserHandle.ALL);
} else {
Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION);
intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA,
@@ -1364,7 +1372,8 @@ public class AdbDebuggingManager {
}
PairDevice device = new PairDevice(fingerprints, hostname, false);
intent.putExtra(AdbManager.WIRELESS_PAIR_DEVICE_EXTRA, device);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent,
UserHandle.ALL);
// Add the key into the keystore
mAdbKeyStore.setLastConnectionTime(publicKey,
System.currentTimeMillis());
@@ -1378,14 +1387,14 @@ public class AdbDebuggingManager {
intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA,
AdbManager.WIRELESS_STATUS_CONNECTED);
intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL);
}
private void sendPairedDevicesToUI(Map<String, PairDevice> devices) {
Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION);
// Map is not serializable, so need to downcast
intent.putExtra(AdbManager.WIRELESS_DEVICES_EXTRA, (HashMap) devices);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL);
}
private void updateUIPairCode(String code) {
@@ -1395,7 +1404,7 @@ public class AdbDebuggingManager {
intent.putExtra(AdbManager.WIRELESS_PAIRING_CODE_EXTRA, code);
intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA,
AdbManager.WIRELESS_STATUS_PAIRING_CODE);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL);
}
}

View File

@@ -431,7 +431,7 @@ public class AdbService extends IAdbManager.Stub {
? AdbManager.WIRELESS_STATUS_CONNECTED
: AdbManager.WIRELESS_STATUS_DISCONNECTED);
intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL);
Slog.i(TAG, "sent port broadcast port=" + port);
}

View File

@@ -23,7 +23,14 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.debug.AdbManager;
import android.debug.IAdbManager;
import android.os.ServiceManager;
import android.provider.Settings;
import android.util.Log;
@@ -105,6 +112,7 @@ public final class AdbDebuggingManagerTest {
public void tearDown() throws Exception {
mKeyStore.deleteKeyStore();
setAllowedConnectionTime(mOriginalAllowedConnectionTime);
dropShellPermissionIdentity();
}
/**
@@ -813,6 +821,108 @@ public final class AdbDebuggingManagerTest {
return hasAtLeastOneLetter;
}
CountDownLatch mAdbActionLatch = new CountDownLatch(1);
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.i(TAG, "Received intent action=" + action);
if (AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION.equals(action)) {
assertEquals("Received broadcast without MANAGE_DEBUGGING permission.",
context.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING),
PackageManager.PERMISSION_GRANTED);
Log.i(TAG, "action=" + action + " paired_device=" + intent.getSerializableExtra(
AdbManager.WIRELESS_DEVICES_EXTRA).toString());
mAdbActionLatch.countDown();
} else if (AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION.equals(action)) {
assertEquals("Received broadcast without MANAGE_DEBUGGING permission.",
context.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING),
PackageManager.PERMISSION_GRANTED);
int status = intent.getIntExtra(AdbManager.WIRELESS_STATUS_EXTRA,
AdbManager.WIRELESS_STATUS_DISCONNECTED);
Log.i(TAG, "action=" + action + " status=" + status);
mAdbActionLatch.countDown();
} else if (AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION.equals(action)) {
assertEquals("Received broadcast without MANAGE_DEBUGGING permission.",
context.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING),
PackageManager.PERMISSION_GRANTED);
Integer res = intent.getIntExtra(
AdbManager.WIRELESS_STATUS_EXTRA,
AdbManager.WIRELESS_STATUS_FAIL);
Log.i(TAG, "action=" + action + " result=" + res);
if (res.equals(AdbManager.WIRELESS_STATUS_PAIRING_CODE)) {
String pairingCode = intent.getStringExtra(
AdbManager.WIRELESS_PAIRING_CODE_EXTRA);
Log.i(TAG, "pairingCode=" + pairingCode);
} else if (res.equals(AdbManager.WIRELESS_STATUS_CONNECTED)) {
int port = intent.getIntExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, 0);
Log.i(TAG, "port=" + port);
}
mAdbActionLatch.countDown();
}
}
};
private void adoptShellPermissionIdentity() {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.adoptShellPermissionIdentity(android.Manifest.permission.MANAGE_DEBUGGING);
}
private void dropShellPermissionIdentity() {
InstrumentationRegistry.getInstrumentation().getUiAutomation()
.dropShellPermissionIdentity();
}
@Test
public void testBroadcastReceiverWithPermissions() throws Exception {
adoptShellPermissionIdentity();
final IAdbManager mAdbManager = IAdbManager.Stub.asInterface(
ServiceManager.getService(Context.ADB_SERVICE));
IntentFilter intentFilter =
new IntentFilter(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION);
intentFilter.addAction(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION);
intentFilter.addAction(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION);
assertEquals("Context does not have MANAGE_DEBUGGING permission.",
mContext.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING),
PackageManager.PERMISSION_GRANTED);
try {
mContext.registerReceiver(mReceiver, intentFilter);
mAdbManager.enablePairingByPairingCode();
if (!mAdbActionLatch.await(TIMEOUT, TIMEOUT_TIME_UNIT)) {
fail("Receiver did not receive adb intent action within the timeout duration");
}
} finally {
mContext.unregisterReceiver(mReceiver);
}
}
@Test
public void testBroadcastReceiverWithoutPermissions() throws Exception {
adoptShellPermissionIdentity();
final IAdbManager mAdbManager = IAdbManager.Stub.asInterface(
ServiceManager.getService(Context.ADB_SERVICE));
IntentFilter intentFilter =
new IntentFilter(AdbManager.WIRELESS_DEBUG_PAIRED_DEVICES_ACTION);
intentFilter.addAction(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION);
intentFilter.addAction(AdbManager.WIRELESS_DEBUG_PAIRING_RESULT_ACTION);
mAdbManager.enablePairingByPairingCode();
dropShellPermissionIdentity();
assertEquals("Context has MANAGE_DEBUGGING permission.",
mContext.checkSelfPermission(android.Manifest.permission.MANAGE_DEBUGGING),
PackageManager.PERMISSION_DENIED);
try {
mContext.registerReceiver(mReceiver, intentFilter);
if (mAdbActionLatch.await(TIMEOUT, TIMEOUT_TIME_UNIT)) {
fail("Broadcast receiver received adb action intent without debug permissions");
}
} finally {
mContext.unregisterReceiver(mReceiver);
}
}
/**
* Runs an adb test with the provided configuration.
*