Re: [PATCH] Bluetooth: Fix updating connecton state in `hci_encrypt_cfm`

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Patrick,

On Wed, Jul 15, 2020 at 7:50 AM Patrick Steinhardt <ps@xxxxxx> wrote:
>
> Starting with the upgrade to v5.8-rc3, I've noticed I wasn't able to
> connect to my Bluetooth headset properly anymore. While connecting to
> the device would eventually succeed, bluetoothd seemed to be confused
> about the current connection state where the state was flapping hence
> and forth. Bisecting this issue led to commit 3ca44c16b0dc ("Bluetooth:
> Consolidate encryption handling in hci_encrypt_cfm"), which refactored
> `hci_encrypt_cfm` to also handle updating the connection state.
>
> The commit in question changed the code to call `hci_connect_cfm` inside
> `hci_encrypt_cfm` and updating the connection state. But the conversion
> didn't keep old behaviour of when the connection state is updated, which
> now causes us to not properly update it anymore.
>
> Fix the issue by adding another parameter to the function that allows
> callers to specify whether the connection state should be updated, which
> allows us to restore previous behaviour.
>
> Fixes: 3ca44c16b0dc ("Bluetooth: Consolidate encryption handling in hci_encrypt_cfm")
> Signed-off-by: Patrick Steinhardt <ps@xxxxxx>
> ---
>  include/net/bluetooth/hci_core.h | 4 ++--
>  net/bluetooth/hci_event.c        | 6 +++---
>  2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index cdd4f1db8670..9abcc4a89abc 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -1381,13 +1381,13 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
>                 conn->security_cfm_cb(conn, status);
>  }
>
> -static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
> +static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 update_state)
>  {
>         struct hci_cb *cb;
>         __u8 encrypt;
>
>         if (conn->state == BT_CONFIG) {
> -               if (status)
> +               if (update_state)

The intent was actually to have if (!status) as it means the
encryption has succeeded the state can be considered connected, so I
wonder if we really need to introduce another parameter. Anyway as it
is broken we need to come up with a fix rather quickly.

>                         conn->state = BT_CONNECTED;
>
>                 hci_connect_cfm(conn, status);
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index cfeaee347db3..483d35eda2f1 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -2931,7 +2931,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
>                                      &cp);
>                 } else {
>                         clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
> -                       hci_encrypt_cfm(conn, ev->status);
> +                       hci_encrypt_cfm(conn, ev->status, 0);
>                 }
>         }
>
> @@ -3016,7 +3016,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
>                 conn->enc_key_size = rp->key_size;
>         }
>
> -       hci_encrypt_cfm(conn, 0);
> +       hci_encrypt_cfm(conn, 0, 1);
>
>  unlock:
>         hci_dev_unlock(hdev);
> @@ -3134,7 +3134,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
>         }
>
>  notify:
> -       hci_encrypt_cfm(conn, ev->status);
> +       hci_encrypt_cfm(conn, ev->status, !ev->status);
>
>  unlock:
>         hci_dev_unlock(hdev);
> --
> 2.27.0
>


-- 
Luiz Augusto von Dentz



[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux