From 6799e4b038c33ce3fd175749ebdea69379a5489f Mon Sep 17 00:00:00 2001 From: Himanshu Rawat Date: Mon, 8 Apr 2024 19:44:45 +0000 Subject: [PATCH] RESTRICT AUTOMERGE Disallow unexpected incoming HID connections 2/2 HID profile accepted any new incoming HID connection. Even when the connection policy disabled HID connection, remote devices could initiate HID connection. This change ensures that incoming HID connection are accepted only if application was interested in that HID connection. This vulnerarbility no longer exists on the main because of feature request b/324093729. Test: Manual | Pair and connect a HID device, disable HID connection from Bluetooth device setting, attempt to connect from the HID device. Bug: 308429049 Ignore-AOSP-First: security (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5fc87e65eb3d70f051e2902d3e81ce6587ab1a96) Merged-In: I1d7e886b1045d026f96c8274aca86dc499f87777 Change-Id: I1d7e886b1045d026f96c8274aca86dc499f87777 --- jni/com_android_bluetooth_hid_host.cpp | 8 +++++--- src/com/android/bluetooth/hid/HidHostService.java | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/jni/com_android_bluetooth_hid_host.cpp b/jni/com_android_bluetooth_hid_host.cpp index cab5e3361..22c7dcfe8 100644 --- a/jni/com_android_bluetooth_hid_host.cpp +++ b/jni/com_android_bluetooth_hid_host.cpp @@ -284,7 +284,8 @@ static jboolean connectHidNative(JNIEnv* env, jobject object, } static jboolean disconnectHidNative(JNIEnv* env, jobject object, - jbyteArray address) { + jbyteArray address, + jboolean reconnect_allowed) { jbyte* addr; jboolean ret = JNI_TRUE; if (!sBluetoothHidInterface) return JNI_FALSE; @@ -295,7 +296,8 @@ static jboolean disconnectHidNative(JNIEnv* env, jobject object, return JNI_FALSE; } - bt_status_t status = sBluetoothHidInterface->disconnect((RawAddress*)addr); + bt_status_t status = + sBluetoothHidInterface->disconnect((RawAddress*)addr, reconnect_allowed); if (status != BT_STATUS_SUCCESS) { ALOGE("Failed disconnect hid channel, status: %d", status); ret = JNI_FALSE; @@ -511,7 +513,7 @@ static JNINativeMethod sMethods[] = { {"initializeNative", "()V", (void*)initializeNative}, {"cleanupNative", "()V", (void*)cleanupNative}, {"connectHidNative", "([B)Z", (void*)connectHidNative}, - {"disconnectHidNative", "([B)Z", (void*)disconnectHidNative}, + {"disconnectHidNative", "([BZ)Z", (void*)disconnectHidNative}, {"getProtocolModeNative", "([B)Z", (void*)getProtocolModeNative}, {"virtualUnPlugNative", "([B)Z", (void*)virtualUnPlugNative}, {"setProtocolModeNative", "([BB)Z", (void*)setProtocolModeNative}, diff --git a/src/com/android/bluetooth/hid/HidHostService.java b/src/com/android/bluetooth/hid/HidHostService.java index 10d414d46..ed35c2908 100644 --- a/src/com/android/bluetooth/hid/HidHostService.java +++ b/src/com/android/bluetooth/hid/HidHostService.java @@ -161,7 +161,10 @@ public void handleMessage(Message msg) { break; case MESSAGE_DISCONNECT: { BluetoothDevice device = (BluetoothDevice) msg.obj; - if (!disconnectHidNative(Utils.getByteAddress(device))) { + int connectionPolicy = getConnectionPolicy(device); + boolean reconnectAllowed = + connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED; + if (!disconnectHidNative(Utils.getByteAddress(device), reconnectAllowed)) { broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTING); broadcastConnectionState(device, BluetoothProfile.STATE_DISCONNECTED); break; @@ -934,7 +937,7 @@ public void dump(StringBuilder sb) { private native boolean connectHidNative(byte[] btAddress); - private native boolean disconnectHidNative(byte[] btAddress); + private native boolean disconnectHidNative(byte[] btAddress, boolean reconnectAllowed); private native boolean getProtocolModeNative(byte[] btAddress);