aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-05-02 21:24:06 -0400
committerMarcel Holtmann <marcel@holtmann.org>2009-05-04 17:29:02 -0400
commita67e899cf38ae542d1a028ccd021f9189f76fb74 (patch)
treed0bb79ccbdd5737745e99acbc569605bc74bc446 /net/bluetooth/hci_conn.c
parent9f722c0978b04acba209f8ca1896ad05814bc3a3 (diff)
Bluetooth: Fix issue with sysfs handling for connections
Due to a semantic changes in flush_workqueue() the current approach of synchronizing the sysfs handling for connections doesn't work anymore. The whole approach is actually fully broken and based on assumptions that are no longer valid. With the introduction of Simple Pairing support, the creation of low-level ACL links got changed. This change invalidates the reason why in the past two independent work queues have been used for adding/removing sysfs devices. The adding of the actual sysfs device is now postponed until the host controller successfully assigns an unique handle to that link. So the real synchronization happens inside the controller and not the host. The only left-over problem is that some internals of the sysfs device handling are not initialized ahead of time. This leaves potential access to invalid data and can cause various NULL pointer dereferences. To fix this a new function makes sure that all sysfs details are initialized when an connection attempt is made. The actual sysfs device is only registered when the connection has been successfully established. To avoid a race condition with the registration, the check if a device is registered has been moved into the removal work. As an extra protection two flush_work() calls are left in place to make sure a previous add/del work has been completed first. Based on a report by Marc Pignat <marc.pignat@hevs.ch> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Tested-by: Justin P. Mattock <justinmattock@gmail.com> Tested-by: Roger Quadros <ext-roger.quadros@nokia.com> Tested-by: Marc Pignat <marc.pignat@hevs.ch>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 375f4b4f7f79..61309b26f271 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -248,6 +248,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
248 if (hdev->notify) 248 if (hdev->notify)
249 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); 249 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
250 250
251 hci_conn_init_sysfs(conn);
252
251 tasklet_enable(&hdev->tx_task); 253 tasklet_enable(&hdev->tx_task);
252 254
253 return conn; 255 return conn;