summaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_sock.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2014-06-29 12:13:05 +0200
committerMarcel Holtmann <marcel@holtmann.org>2014-07-03 17:42:49 +0200
commitfee746b0babf128a50ece050ee6e63003ebb5ae1 (patch)
tree4a3c3b7ca76f43ddda0f85b006c023e298d1c3ed /net/bluetooth/hci_sock.c
parentBluetooth: Add support for Get Clock Info mgmt command (diff)
downloadlinux-fee746b0babf128a50ece050ee6e63003ebb5ae1.tar.xz
linux-fee746b0babf128a50ece050ee6e63003ebb5ae1.zip
Bluetooth: Restrict access for raw-only controllers
Bluetooth controllers that are marked for raw-only usage can only be used with user channel access. Any other operation should be rejected. This simplifies the whole raw-only support since it now depends on the fact that the controller is marked with HCI_QUIRK_RAW_DEVICE and runtime raw access is restricted to user channel operation. The kernel internal processing of HCI commands and events is designed around the case that either the kernel has full control over the device or that the device is driven from userspace. This now makes a clear distinction between these two possible operation modes. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth/hci_sock.c')
-rw-r--r--net/bluetooth/hci_sock.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 80d25c150a65..54e4e8fd5d97 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -453,7 +453,8 @@ static int hci_sock_release(struct socket *sock)
if (hdev) {
if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
- mgmt_index_added(hdev);
+ if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+ mgmt_index_added(hdev);
clear_bit(HCI_USER_CHANNEL, &hdev->dev_flags);
hci_dev_close(hdev->id);
}
@@ -517,6 +518,9 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
if (test_bit(HCI_USER_CHANNEL, &hdev->dev_flags))
return -EBUSY;
+ if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+ return -EOPNOTSUPP;
+
if (hdev->dev_type != HCI_BREDR)
return -EOPNOTSUPP;
@@ -702,12 +706,14 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
goto done;
}
- mgmt_index_removed(hdev);
+ if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+ mgmt_index_removed(hdev);
err = hci_dev_open(hdev->id);
if (err) {
clear_bit(HCI_USER_CHANNEL, &hdev->dev_flags);
- mgmt_index_added(hdev);
+ if (!test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks))
+ mgmt_index_added(hdev);
hci_dev_put(hdev);
goto done;
}
@@ -960,7 +966,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
goto drop;
}
- if (test_bit(HCI_RAW, &hdev->flags) || (ogf == 0x3f)) {
+ if (ogf == 0x3f) {
skb_queue_tail(&hdev->raw_q, skb);
queue_work(hdev->workqueue, &hdev->tx_work);
} else {