OSDN Git Service

Bluetooth: L2CAP: Delay identity address updates
authorLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 9 Mar 2023 00:16:31 +0000 (16:16 -0800)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Mon, 24 Apr 2023 04:48:44 +0000 (21:48 -0700)
This delays the identity address updates to give time for userspace to
process the new address otherwise there is a risk that userspace
creates a duplicated device if the MGMT event is delayed for some
reason.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
include/net/bluetooth/l2cap.h
net/bluetooth/l2cap_core.c
net/bluetooth/smp.c

index 2f766e3..cf393e7 100644 (file)
@@ -694,7 +694,7 @@ struct l2cap_conn {
        struct sk_buff_head     pending_rx;
        struct work_struct      pending_rx_work;
 
-       struct work_struct      id_addr_update_work;
+       struct delayed_work     id_addr_timer;
 
        __u8                    disc_reason;
 
index 55a7226..5cc95fd 100644 (file)
@@ -745,7 +745,7 @@ EXPORT_SYMBOL_GPL(l2cap_chan_list);
 static void l2cap_conn_update_id_addr(struct work_struct *work)
 {
        struct l2cap_conn *conn = container_of(work, struct l2cap_conn,
-                                              id_addr_update_work);
+                                              id_addr_timer.work);
        struct hci_conn *hcon = conn->hcon;
        struct l2cap_chan *chan;
 
@@ -1907,8 +1907,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
        if (work_pending(&conn->pending_rx_work))
                cancel_work_sync(&conn->pending_rx_work);
 
-       if (work_pending(&conn->id_addr_update_work))
-               cancel_work_sync(&conn->id_addr_update_work);
+       cancel_delayed_work_sync(&conn->id_addr_timer);
 
        l2cap_unregister_all_users(conn);
 
@@ -7874,7 +7873,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)
 
        skb_queue_head_init(&conn->pending_rx);
        INIT_WORK(&conn->pending_rx_work, process_pending_rx);
-       INIT_WORK(&conn->id_addr_update_work, l2cap_conn_update_id_addr);
+       INIT_DELAYED_WORK(&conn->id_addr_timer, l2cap_conn_update_id_addr);
 
        conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM;
 
index 7066322..f1a9fc0 100644 (file)
@@ -58,6 +58,8 @@
 
 #define SMP_TIMEOUT    msecs_to_jiffies(30000)
 
+#define ID_ADDR_TIMEOUT        msecs_to_jiffies(200)
+
 #define AUTH_REQ_MASK(dev)     (hci_dev_test_flag(dev, HCI_SC_ENABLED) ? \
                                 0x3f : 0x07)
 #define KEY_DIST_MASK          0x07
@@ -1067,7 +1069,12 @@ static void smp_notify_keys(struct l2cap_conn *conn)
                if (hcon->type == LE_LINK) {
                        bacpy(&hcon->dst, &smp->remote_irk->bdaddr);
                        hcon->dst_type = smp->remote_irk->addr_type;
-                       queue_work(hdev->workqueue, &conn->id_addr_update_work);
+                       /* Use a short delay to make sure the new address is
+                        * propagated _before_ the channels.
+                        */
+                       queue_delayed_work(hdev->workqueue,
+                                          &conn->id_addr_timer,
+                                          ID_ADDR_TIMEOUT);
                }
        }