Re: [PATCH v2] adapter: Fix link key address type for old kernels

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

 



Hi Xiao,

On Wed, Dec 20, 2023 at 12:31 PM Xiao Yao <xiaokeqinhealth@xxxxxxx> wrote:
>
> From: Xiao Yao <xiaoyao@xxxxxxxxxxxxxx>
>
> According to the Bluetooth specification, the address
> type of the link key is not fixed. However, the
> load_link_keys function in the old kernel code requires
> that the address type must be BDADDR_BREDR, so attempt
> it when the first load fails.
>
> Fixes: https://github.com/bluez/bluez/issues/686
>
> Signed-off-by: Xiao Yao <xiaoyao@xxxxxxxxxxxxxx>
> ---
> v1 -> v2
> Prioritize loading keys with standard address types,
> and switch to BREDR address types upon failure, as
> suggested by the maintainer.
> ---
>  src/adapter.c | 45 ++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 36 insertions(+), 9 deletions(-)
>
> diff --git a/src/adapter.c b/src/adapter.c
> index ee70b00d2..e1b704ecc 100644
> --- a/src/adapter.c
> +++ b/src/adapter.c
> @@ -168,6 +168,9 @@ static GSList *adapter_drivers = NULL;
>  static GSList *disconnect_list = NULL;
>  static GSList *conn_fail_list = NULL;
>
> +static GSList *link_keys = NULL;
> +static bool link_keys_brder = false;
> +
>  struct link_key_info {
>         bdaddr_t bdaddr;
>         uint8_t bdaddr_type;
> @@ -4284,23 +4287,45 @@ static int set_privacy(struct btd_adapter *adapter, uint8_t privacy)
>         return -1;
>  }
>
> +static void load_link_keys(struct btd_adapter *adapter, GSList *keys,
> +                          bool debug_keys, bool link_key_bredr);
> +
>  static void load_link_keys_complete(uint8_t status, uint16_t length,
>                                         const void *param, void *user_data)
>  {
>         struct btd_adapter *adapter = user_data;
>
>         if (status != MGMT_STATUS_SUCCESS) {
> +               /*
> +                * According to the Bluetooth specification, the address
> +                * type of the link key is not fixed. However, the
> +                * load_link_keys function in the old kernel code requires
> +                * that the address type must be BDADDR_BREDR, so attempt it.
> +                */
> +               if (link_keys_brder == false && status == 0x0d) {
> +                       link_keys_brder = true;
> +                       load_link_keys(adapter, link_keys, btd_opts.debug_keys,
> +                                      link_keys_brder);
> +                       return;
> +               }
> +
>                 btd_error(adapter->dev_id,
>                         "Failed to load link keys for hci%u: %s (0x%02x)",
>                                 adapter->dev_id, mgmt_errstr(status), status);
> -               return;
> +
> +               goto free;
>         }
>
>         DBG("link keys loaded for hci%u", adapter->dev_id);
> +
> +free:
> +       g_slist_free_full(link_keys, g_free);
> +       link_keys = NULL;
> +       link_keys_brder = false;
>  }
>
>  static void load_link_keys(struct btd_adapter *adapter, GSList *keys,
> -                                                       bool debug_keys)
> +                          bool debug_keys, bool link_key_bredr)
>  {
>         struct mgmt_cp_load_link_keys *cp;
>         struct mgmt_link_key_info *key;
> @@ -4320,8 +4345,8 @@ static void load_link_keys(struct btd_adapter *adapter, GSList *keys,
>
>         key_count = g_slist_length(keys);
>
> -       DBG("hci%u keys %zu debug_keys %d", adapter->dev_id, key_count,
> -                                                               debug_keys);
> +       DBG("hci%u keys %zu debug_keys %d (%s)", adapter->dev_id, key_count,
> +                       debug_keys, link_key_bredr ? "force bredr" : "normal");
>
>         cp_size = sizeof(*cp) + (key_count * sizeof(*key));
>
> @@ -4347,7 +4372,10 @@ static void load_link_keys(struct btd_adapter *adapter, GSList *keys,
>                 struct link_key_info *info = l->data;
>
>                 bacpy(&key->addr.bdaddr, &info->bdaddr);
> -               key->addr.type = info->bdaddr_type;
> +               if (link_key_bredr)
> +                       key->addr.type = BDADDR_BREDR;
> +               else
> +                       key->addr.type = info->bdaddr_type;
>                 key->type = info->type;
>                 memcpy(key->val, info->key, 16);
>                 key->pin_len = info->pin_len;
> @@ -4873,7 +4901,6 @@ done:
>  static void load_devices(struct btd_adapter *adapter)
>  {
>         char dirname[PATH_MAX];
> -       GSList *keys = NULL;
>         GSList *ltks = NULL;
>         GSList *irks = NULL;
>         GSList *params = NULL;
> @@ -4964,7 +4991,7 @@ static void load_devices(struct btd_adapter *adapter)
>                 }
>
>                 if (key_info)
> -                       keys = g_slist_append(keys, key_info);
> +                       link_keys = g_slist_append(link_keys, key_info);
>
>                 if (ltk_info)
>                         ltks = g_slist_append(ltks, ltk_info);
> @@ -5013,8 +5040,8 @@ free:
>
>         closedir(dir);
>
> -       load_link_keys(adapter, keys, btd_opts.debug_keys);
> -       g_slist_free_full(keys, g_free);
> +       load_link_keys(adapter, link_keys, btd_opts.debug_keys,
> +                       link_keys_brder);
>
>         load_ltks(adapter, ltks);
>         g_slist_free_full(ltks, g_free);
> --
> 2.34.1

Ive just sent a similar fix:

https://patchwork.kernel.org/project/bluetooth/patch/20231220172222.2333064-1-luiz.dentz@xxxxxxxxx/

>


-- 
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