@@ -3068,6 +3068,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
3068
3068
struct hci_ev_conn_complete * ev = data ;
3069
3069
struct hci_conn * conn ;
3070
3070
3071
+ if (__le16_to_cpu (ev -> handle ) > HCI_CONN_HANDLE_MAX ) {
3072
+ bt_dev_err (hdev , "Ignoring HCI_Connection_Complete for invalid handle" );
3073
+ return ;
3074
+ }
3075
+
3071
3076
bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
3072
3077
3073
3078
hci_dev_lock (hdev );
@@ -3106,6 +3111,17 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
3106
3111
}
3107
3112
}
3108
3113
3114
+ /* The HCI_Connection_Complete event is only sent once per connection.
3115
+ * Processing it more than once per connection can corrupt kernel memory.
3116
+ *
3117
+ * As the connection handle is set here for the first time, it indicates
3118
+ * whether the connection is already set up.
3119
+ */
3120
+ if (conn -> handle != HCI_CONN_HANDLE_UNSET ) {
3121
+ bt_dev_err (hdev , "Ignoring HCI_Connection_Complete for existing connection" );
3122
+ goto unlock ;
3123
+ }
3124
+
3109
3125
if (!ev -> status ) {
3110
3126
conn -> handle = __le16_to_cpu (ev -> handle );
3111
3127
@@ -4674,6 +4690,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
4674
4690
return ;
4675
4691
}
4676
4692
4693
+ if (__le16_to_cpu (ev -> handle ) > HCI_CONN_HANDLE_MAX ) {
4694
+ bt_dev_err (hdev , "Ignoring HCI_Sync_Conn_Complete for invalid handle" );
4695
+ return ;
4696
+ }
4697
+
4677
4698
bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
4678
4699
4679
4700
hci_dev_lock (hdev );
@@ -4697,23 +4718,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
4697
4718
goto unlock ;
4698
4719
}
4699
4720
4721
+ /* The HCI_Synchronous_Connection_Complete event is only sent once per connection.
4722
+ * Processing it more than once per connection can corrupt kernel memory.
4723
+ *
4724
+ * As the connection handle is set here for the first time, it indicates
4725
+ * whether the connection is already set up.
4726
+ */
4727
+ if (conn -> handle != HCI_CONN_HANDLE_UNSET ) {
4728
+ bt_dev_err (hdev , "Ignoring HCI_Sync_Conn_Complete event for existing connection" );
4729
+ goto unlock ;
4730
+ }
4731
+
4700
4732
switch (ev -> status ) {
4701
4733
case 0x00 :
4702
- /* The synchronous connection complete event should only be
4703
- * sent once per new connection. Receiving a successful
4704
- * complete event when the connection status is already
4705
- * BT_CONNECTED means that the device is misbehaving and sent
4706
- * multiple complete event packets for the same new connection.
4707
- *
4708
- * Registering the device more than once can corrupt kernel
4709
- * memory, hence upon detecting this invalid event, we report
4710
- * an error and ignore the packet.
4711
- */
4712
- if (conn -> state == BT_CONNECTED ) {
4713
- bt_dev_err (hdev , "Ignoring connect complete event for existing connection" );
4714
- goto unlock ;
4715
- }
4716
-
4717
4734
conn -> handle = __le16_to_cpu (ev -> handle );
4718
4735
conn -> state = BT_CONNECTED ;
4719
4736
conn -> type = ev -> link_type ;
@@ -5509,6 +5526,11 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
5509
5526
struct smp_irk * irk ;
5510
5527
u8 addr_type ;
5511
5528
5529
+ if (handle > HCI_CONN_HANDLE_MAX ) {
5530
+ bt_dev_err (hdev , "Ignoring HCI_LE_Connection_Complete for invalid handle" );
5531
+ return ;
5532
+ }
5533
+
5512
5534
hci_dev_lock (hdev );
5513
5535
5514
5536
/* 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,
5550
5572
cancel_delayed_work (& conn -> le_conn_timeout );
5551
5573
}
5552
5574
5575
+ /* The HCI_LE_Connection_Complete event is only sent once per connection.
5576
+ * Processing it more than once per connection can corrupt kernel memory.
5577
+ *
5578
+ * As the connection handle is set here for the first time, it indicates
5579
+ * whether the connection is already set up.
5580
+ */
5581
+ if (conn -> handle != HCI_CONN_HANDLE_UNSET ) {
5582
+ bt_dev_err (hdev , "Ignoring HCI_Connection_Complete for existing connection" );
5583
+ goto unlock ;
5584
+ }
5585
+
5553
5586
le_conn_update_addr (conn , bdaddr , bdaddr_type , local_rpa );
5554
5587
5555
5588
/* Lookup the identity address from the stored connection
0 commit comments