@@ -3068,6 +3068,11 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
30683068 struct hci_ev_conn_complete * ev = data ;
30693069 struct hci_conn * conn ;
30703070
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+
30713076 bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
30723077
30733078 hci_dev_lock (hdev );
@@ -3106,6 +3111,17 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31063111 }
31073112 }
31083113
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+
31093125 if (!ev -> status ) {
31103126 conn -> handle = __le16_to_cpu (ev -> handle );
31113127
@@ -4674,6 +4690,11 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
46744690 return ;
46754691 }
46764692
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+
46774698 bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
46784699
46794700 hci_dev_lock (hdev );
@@ -4697,23 +4718,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, void *data,
46974718 goto unlock ;
46984719 }
46994720
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+
47004732 switch (ev -> status ) {
47014733 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-
47174734 conn -> handle = __le16_to_cpu (ev -> handle );
47184735 conn -> state = BT_CONNECTED ;
47194736 conn -> type = ev -> link_type ;
@@ -5509,6 +5526,11 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
55095526 struct smp_irk * irk ;
55105527 u8 addr_type ;
55115528
5529+ if (handle > HCI_CONN_HANDLE_MAX ) {
5530+ bt_dev_err (hdev , "Ignoring HCI_LE_Connection_Complete for invalid handle" );
5531+ return ;
5532+ }
5533+
55125534 hci_dev_lock (hdev );
55135535
55145536 /* 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,
55505572 cancel_delayed_work (& conn -> le_conn_timeout );
55515573 }
55525574
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+
55535586 le_conn_update_addr (conn , bdaddr , bdaddr_type , local_rpa );
55545587
55555588 /* Lookup the identity address from the stored connection
0 commit comments