aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2013-12-17 06:21:25 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2013-12-17 06:47:27 -0500
commit1bc5ad168f441f6f8bfd944288a5f7b4963ac1f6 (patch)
tree2cbf8a686a7d16844a32938ee81a09c3846fb572 /net/bluetooth
parentbd0976dd3379e790b031cef7f477c58b82a65fc2 (diff)
Bluetooth: Fix HCI User Channel permission check in hci_sock_sendmsg
The HCI User Channel is an admin operation which enforces CAP_NET_ADMIN when binding the socket. Problem now is that it then requires also CAP_NET_RAW when calling into hci_sock_sendmsg. This is not intended and just an oversight since general HCI sockets (which do not require special permission to bind) and HCI User Channel share the same code path here. Remove the extra CAP_NET_RAW check for HCI User Channel write operation since the permission check has already been enforced when binding the socket. This also makes it possible to open HCI User Channel from a privileged process and then hand the file descriptor to an unprivilged process. Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Tested-by: Samuel Ortiz <sameo@linux.intel.com> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_sock.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 71f0be173080..73bf644c7c74 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -942,8 +942,22 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
942 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data); 942 bt_cb(skb)->pkt_type = *((unsigned char *) skb->data);
943 skb_pull(skb, 1); 943 skb_pull(skb, 1);
944 944
945 if (hci_pi(sk)->channel == HCI_CHANNEL_RAW && 945 if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
946 bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) { 946 /* No permission check is needed for user channel
947 * since that gets enforced when binding the socket.
948 *
949 * However check that the packet type is valid.
950 */
951 if (bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
952 bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
953 bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
954 err = -EINVAL;
955 goto drop;
956 }
957
958 skb_queue_tail(&hdev->raw_q, skb);
959 queue_work(hdev->workqueue, &hdev->tx_work);
960 } else if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
947 u16 opcode = get_unaligned_le16(skb->data); 961 u16 opcode = get_unaligned_le16(skb->data);
948 u16 ogf = hci_opcode_ogf(opcode); 962 u16 ogf = hci_opcode_ogf(opcode);
949 u16 ocf = hci_opcode_ocf(opcode); 963 u16 ocf = hci_opcode_ocf(opcode);
@@ -974,14 +988,6 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
974 goto drop; 988 goto drop;
975 } 989 }
976 990
977 if (hci_pi(sk)->channel == HCI_CHANNEL_USER &&
978 bt_cb(skb)->pkt_type != HCI_COMMAND_PKT &&
979 bt_cb(skb)->pkt_type != HCI_ACLDATA_PKT &&
980 bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) {
981 err = -EINVAL;
982 goto drop;
983 }
984
985 skb_queue_tail(&hdev->raw_q, skb); 991 skb_queue_tail(&hdev->raw_q, skb);
986 queue_work(hdev->workqueue, &hdev->tx_work); 992 queue_work(hdev->workqueue, &hdev->tx_work);
987 } 993 }