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:
@@ -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";
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user