From: "Matthias Wauer (PRETTL)" <Matthias.Wauer@xxxxxxxxxxxxxxxxxxxxxx> hci_conn_hash_lookup_handle can fail to find the correct hci_conn object if the actual handle value is 0 and more than one hci_conn object is around, for example when connection attempts are pending (also handle value 0). On an external disconnection event this might free the wrong object and not cleanup the sysfs entry on disconnection and lead to the following when handle 0 is reused by the controller for a new connection. Additionally the device will still be considered connected and connection attempts are canceled. Workqueue: hci0 hci_rx_work [<80112334>] (unwind_backtrace) from [<8010d108>] (show_stack+0x20/0x24) [<8010d108>] (show_stack) from [<809b8a44>] (dump_stack+0x80/0x94) [<809b8a44>] (dump_stack) from [<8012faa4>] (__warn+0xec/0x114) [<8012faa4>] (__warn) from [<8012fb14>] (warn_slowpath_fmt+0x48/0x50) [<8012fb14>] (warn_slowpath_fmt) from [<802e2be0>] (sysfs_warn_dup+0x78/0x88) [<802e2be0>] (sysfs_warn_dup) from [<802e2cd0>] (sysfs_create_dir_ns+0x8c/0x9c) [<802e2cd0>] (sysfs_create_dir_ns) from [<809bd48c>] (kobject_add_internal+0xb8/0x328) [<809bd48c>] (kobject_add_internal) from [<809bd8d4>] (kobject_add+0x50/0x98) [<809bd8d4>] (kobject_add) from [<805ac308>] (device_add+0x114/0x5e4) [<805ac308>] (device_add) from [<8095fbf0>] (hci_conn_add_sysfs+0x5c/0xb0) [<8095fbf0>] (hci_conn_add_sysfs) from [<8094b6c4>] (hci_le_meta_evt+0xb9c/0x11b8) [<8094b6c4>] (hci_le_meta_evt) from [<8094c510>] (hci_event_packet+0x830/0x2e60) [<8094c510>] (hci_event_packet) from [<8093aaa4>] (hci_rx_work+0x1e0/0x3c0) [<8093aaa4>] (hci_rx_work) from [<8014ab5c>] (process_one_work+0x1f8/0x590) [<8014ab5c>] (process_one_work) from [<8014ba70>] (worker_thread+0x6c/0x588) [<8014ba70>] (worker_thread) from [<801512b4>] (kthread+0x170/0x178) [<801512b4>] (kthread) from [<80108f28>] (ret_from_fork+0x14/0x2c) kobject_add_internal failed for hci0:0 with -EEXIST, don't try to register things with the same name in the same directory. Signed-off-by: Matthias Wauer (PRETTL) <Matthias.Wauer@xxxxxxxxxxxxxxxxxxxxxx> --- include/net/bluetooth/hci.h | 2 ++ net/bluetooth/hci_conn.c | 1 + 2 files changed, 3 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 5bc1e30dedde..9e5029f77e0c 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -512,6 +512,8 @@ enum { /* The core spec defines 127 as the "not available" value */ #define HCI_TX_POWER_INVALID 127 #define HCI_RSSI_INVALID 127 +/* The core spec defines 0xfff as invalid reserved handle value */ +#define HCI_CONN_HANDLE_INVALID 0xFFF #define HCI_ROLE_MASTER 0x00 #define HCI_ROLE_SLAVE 0x01 diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index ad5b0ac1f9ce..bb3022236e8d 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -502,6 +502,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, if (!conn) return NULL; + conn->handle = HCI_CONN_HANDLE_INVALID; bacpy(&conn->dst, dst); bacpy(&conn->src, &hdev->bdaddr); conn->hdev = hdev; -- 2.17.1