All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2] Bluetooth: hci_event: Ignore multiple conn complete events
@ 2022-01-23 14:06 Soenke Huster
  2022-01-23 14:53 ` [RFC,v2] " bluez.test.bot
  0 siblings, 1 reply; 3+ messages in thread
From: Soenke Huster @ 2022-01-23 14:06 UTC (permalink / raw)
  To: Marcel Holtmann, Johan Hedberg, Luiz Augusto von Dentz,
	David S. Miller, Jakub Kicinski
  Cc: Soenke Huster, linux-bluetooth, netdev, linux-kernel

When one of the three connection complete events is received multiple
times for the same handle, the device is registered multiple times which
leads to memory corruptions. Therefore, consequent events for a single
connection are ignored.

The conn->state can hold different values, therefore HCI_CONN_HANDLE_UNSET
is introduced to identify new connections. To make sure the events do not
contain this or another invalid handle HCI_CONN_HANDLE_MAX and checks
are introduced.

Buglink: https://bugzilla.kernel.org/show_bug.cgi?id=215497
Signed-off-by: Soenke Huster <soenke.huster@eknoes.de>
---
v2: 
- Introduce HCI_CONN_HANDLE_UNSET for new connections
- Introduce HCI_CONN_HANDLE_MAX to check for valid handles

While fuzzing I found several UAFs or null pointer dereferences
due to multiple connection complete events. They occur due to
multiple calls to device_register in one of the three connection
complete events. See the bugreport for a more in-depth description.

 include/net/bluetooth/hci_core.h |  3 ++
 net/bluetooth/hci_conn.c         |  1 +
 net/bluetooth/hci_event.c        | 63 ++++++++++++++++++++++++--------
 3 files changed, 52 insertions(+), 15 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 21eadb113a31..f5caff1ddb29 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -303,6 +303,9 @@ struct adv_monitor {
 
 #define HCI_MAX_SHORT_NAME_LENGTH	10
 
+#define HCI_CONN_HANDLE_UNSET		0xffff
+#define HCI_CONN_HANDLE_MAX		0x0eff
+
 /* Min encryption key size to match with SMP */
 #define HCI_MIN_ENC_KEY_SIZE		7
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 04ebe901e86f..d10651108033 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -689,6 +689,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
 
 	bacpy(&conn->dst, dst);
 	bacpy(&conn->src, &hdev->bdaddr);
+	conn->handle = HCI_CONN_HANDLE_UNSET;
 	conn->hdev  = hdev;
 	conn->type  = type;
 	conn->role  = role;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 681c623aa380..664ccf1d8d93 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3068,6 +3068,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
 	struct hci_ev_conn_complete *ev = data;
 	struct hci_conn *conn;
 
+	if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) {
+		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for invalid handle");
+		return;
+	}
+
 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
@@ -3106,6 +3111,17 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
 		}
 	}
 
+	/* The HCI_Connection_Complete event is only sent once per connection.
+	 * Processing it more than once per connection can corrupt kernel memory.
+	 *
+	 * As the connection handle is set here for the first time, it indicates
+	 * whether the connection is already set up.
+	 */
+	if (conn->handle != HCI_CONN_HANDLE_UNSET) {
+		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
+		goto unlock;
+	}
+
 	if (!ev->status) {
 		conn->handle = __le16_to_cpu(ev->handle);
 
@@ -4674,6 +4690,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
 		return;
 	}
 
+	if (__le16_to_cpu(ev->handle) > HCI_CONN_HANDLE_MAX) {
+		bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete for invalid handle");
+		return;
+	}
+
 	bt_dev_dbg(hdev, "status 0x%2.2x", ev->status);
 
 	hci_dev_lock(hdev);
@@ -4697,23 +4718,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
 			goto unlock;
 	}
 
+	/* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
+	 * Processing it more than once per connection can corrupt kernel memory.
+	 *
+	 * As the connection handle is set here for the first time, it indicates
+	 * whether the connection is already set up.
+	 */
+	if (conn->handle != HCI_CONN_HANDLE_UNSET) {
+		bt_dev_err(hdev, "Ignoring HCI_Sync_Conn_Complete event for existing connection");
+		goto unlock;
+	}
+
 	switch (ev->status) {
 	case 0x00:
-		/* The synchronous connection complete event should only be
-		 * sent once per new connection. Receiving a successful
-		 * complete event when the connection status is already
-		 * BT_CONNECTED means that the device is misbehaving and sent
-		 * multiple complete event packets for the same new connection.
-		 *
-		 * Registering the device more than once can corrupt kernel
-		 * memory, hence upon detecting this invalid event, we report
-		 * an error and ignore the packet.
-		 */
-		if (conn->state == BT_CONNECTED) {
-			bt_dev_err(hdev, "Ignoring connect complete event for existing connection");
-			goto unlock;
-		}
-
 		conn->handle = __le16_to_cpu(ev->handle);
 		conn->state  = BT_CONNECTED;
 		conn->type   = ev->link_type;
@@ -5509,6 +5526,11 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
 	struct smp_irk *irk;
 	u8 addr_type;
 
+	if (handle > HCI_CONN_HANDLE_MAX) {
+		bt_dev_err(hdev, "Ignoring HCI_LE_Connection_Complete for invalid handle");
+		return;
+	}
+
 	hci_dev_lock(hdev);
 
 	/* All controllers implicitly stop advertising in the event of a
@@ -5550,6 +5572,17 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
 		cancel_delayed_work(&conn->le_conn_timeout);
 	}
 
+	/* The HCI_LE_Connection_Complete event is only sent once per connection.
+	 * Processing it more than once per connection can corrupt kernel memory.
+	 *
+	 * As the connection handle is set here for the first time, it indicates
+	 * whether the connection is already set up.
+	 */
+	if (conn->handle != HCI_CONN_HANDLE_UNSET) {
+		bt_dev_err(hdev, "Ignoring HCI_Connection_Complete for existing connection");
+		goto unlock;
+	}
+
 	le_conn_update_addr(conn, bdaddr, bdaddr_type, local_rpa);
 
 	/* Lookup the identity address from the stored connection
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* RE: [RFC,v2] Bluetooth: hci_event: Ignore multiple conn complete events
  2022-01-23 14:06 [RFC PATCH v2] Bluetooth: hci_event: Ignore multiple conn complete events Soenke Huster
@ 2022-01-23 14:53 ` bluez.test.bot
  2022-01-25  2:39   ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 3+ messages in thread
From: bluez.test.bot @ 2022-01-23 14:53 UTC (permalink / raw)
  To: linux-bluetooth, soenke.huster

[-- Attachment #1: Type: text/plain, Size: 1320 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=607576

---Test result---

Test Summary:
CheckPatch                    PASS      1.90 seconds
GitLint                       FAIL      0.97 seconds
SubjectPrefix                 PASS      0.85 seconds
BuildKernel                   PASS      30.23 seconds
BuildKernel32                 PASS      27.08 seconds
Incremental Build with patchesPASS      36.92 seconds
TestRunner: Setup             PASS      479.12 seconds
TestRunner: l2cap-tester      PASS      13.54 seconds
TestRunner: bnep-tester       PASS      6.05 seconds
TestRunner: mgmt-tester       PASS      104.38 seconds
TestRunner: rfcomm-tester     PASS      7.51 seconds
TestRunner: sco-tester        PASS      7.71 seconds
TestRunner: smp-tester        PASS      7.54 seconds
TestRunner: userchan-tester   PASS      6.37 seconds

Details
##############################
Test: GitLint - FAIL - 0.97 seconds
Run gitlint with rule in .gitlint
[RFC,v2] Bluetooth: hci_event: Ignore multiple conn complete events
16: B2 Line has trailing whitespace: "v2: "




---
Regards,
Linux Bluetooth


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [RFC,v2] Bluetooth: hci_event: Ignore multiple conn complete events
  2022-01-23 14:53 ` [RFC,v2] " bluez.test.bot
@ 2022-01-25  2:39   ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 3+ messages in thread
From: Luiz Augusto von Dentz @ 2022-01-25  2:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Sönke Huster

Hi Sonke,

On Mon, Jan 24, 2022 at 1:13 AM <bluez.test.bot@gmail.com> wrote:
>
> This is automated email and please do not reply to this email!
>
> Dear submitter,
>
> Thank you for submitting the patches to the linux bluetooth mailing list.
> This is a CI test results with your patch series:
> PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=607576
>
> ---Test result---
>
> Test Summary:
> CheckPatch                    PASS      1.90 seconds
> GitLint                       FAIL      0.97 seconds
> SubjectPrefix                 PASS      0.85 seconds
> BuildKernel                   PASS      30.23 seconds
> BuildKernel32                 PASS      27.08 seconds
> Incremental Build with patchesPASS      36.92 seconds
> TestRunner: Setup             PASS      479.12 seconds
> TestRunner: l2cap-tester      PASS      13.54 seconds
> TestRunner: bnep-tester       PASS      6.05 seconds
> TestRunner: mgmt-tester       PASS      104.38 seconds
> TestRunner: rfcomm-tester     PASS      7.51 seconds
> TestRunner: sco-tester        PASS      7.71 seconds
> TestRunner: smp-tester        PASS      7.54 seconds
> TestRunner: userchan-tester   PASS      6.37 seconds
>
> Details
> ##############################
> Test: GitLint - FAIL - 0.97 seconds
> Run gitlint with rule in .gitlint
> [RFC,v2] Bluetooth: hci_event: Ignore multiple conn complete events
> 16: B2 Line has trailing whitespace: "v2: "
>
>
>
>
> ---
> Regards,
> Linux Bluetooth

Applied, thanks.

-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-01-25  6:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-23 14:06 [RFC PATCH v2] Bluetooth: hci_event: Ignore multiple conn complete events Soenke Huster
2022-01-23 14:53 ` [RFC,v2] " bluez.test.bot
2022-01-25  2:39   ` Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.