summaryrefslogtreecommitdiff
path: root/net/bluetooth
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-04-06 18:28:39 (GMT)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>2013-04-17 05:45:22 (GMT)
commit8d12356f33f819ec0d064e233f7ca8e59eaa38ef (patch)
treeb976b1efc17d3f9d207212253d6cb5167c6b755c /net/bluetooth
parentfc225c3f5d1b6aa6f99c5c300af4605e4923ce79 (diff)
downloadlinux-8d12356f33f819ec0d064e233f7ca8e59eaa38ef.tar.xz
Bluetooth: introduce hci_conn ref-counting
We currently do not allow using hci_conn from outside of HCI-core. However, several other users could make great use of it. This includes HIDP, rfcomm and all other sub-protocols that rely on an active connection. Hence, we now introduce hci_conn ref-counting. We currently never call get_device(). put_device() is exclusively used in hci_conn_del_sysfs(). Hence, we currently never have a greater device-refcnt than 1. Therefore, it is safe to move the put_device() call from hci_conn_del_sysfs() to hci_conn_del() (it's the only caller). In fact, this even fixes a "use-after-free" bug as we access hci_conn after calling hci_conn_del_sysfs() in hci_conn_del(). From now on we can add references to hci_conn objects in other layers (like l2cap_sock, HIDP, rfcomm, ...) and grab a reference via hci_conn_get(). This does _not_ guarantee, that the connection is still alive. But, this isn't what we want. We can simply lock the hci_conn device and use "device_is_registered(hci_conn->dev)" to test that. However, this is hardly necessary as outside users should never rely on the HCI connection to be alive, anyway. Instead, they should solely rely on the device-object to be available. But if sub-devices want the hci_conn object as sysfs parent, they need to be notified when the connection drops. This will be introduced in later patches with l2cap_users. Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_conn.c3
-rw-r--r--net/bluetooth/hci_sysfs.c1
2 files changed, 1 insertions, 3 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 6b5b8e7..6c7f363 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -462,8 +462,7 @@ int hci_conn_del(struct hci_conn *conn)
hci_dev_put(hdev);
- if (conn->handle == 0)
- kfree(conn);
+ hci_conn_put(conn);
return 0;
}
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index ff38561..6fe15c8 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -146,7 +146,6 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
}
device_del(&conn->dev);
- put_device(&conn->dev);
hci_dev_put(hdev);
}