xref: /openbmc/linux/net/bluetooth/hci_sock.c (revision 4f34228b67246ae3b3ab1dc33b980c77c0650ef4)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    BlueZ - Bluetooth protocol stack for Linux
31da177e4SLinus Torvalds    Copyright (C) 2000-2001 Qualcomm Incorporated
41da177e4SLinus Torvalds 
51da177e4SLinus Torvalds    Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
61da177e4SLinus Torvalds 
71da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
81da177e4SLinus Torvalds    it under the terms of the GNU General Public License version 2 as
91da177e4SLinus Torvalds    published by the Free Software Foundation;
101da177e4SLinus Torvalds 
111da177e4SLinus Torvalds    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
121da177e4SLinus Torvalds    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
131da177e4SLinus Torvalds    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
141da177e4SLinus Torvalds    IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
151da177e4SLinus Torvalds    CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
161da177e4SLinus Torvalds    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
171da177e4SLinus Torvalds    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
181da177e4SLinus Torvalds    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds    ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
211da177e4SLinus Torvalds    COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
221da177e4SLinus Torvalds    SOFTWARE IS DISCLAIMED.
231da177e4SLinus Torvalds */
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds /* Bluetooth HCI sockets. */
261da177e4SLinus Torvalds 
278c520a59SGustavo Padovan #include <linux/export.h>
28787b306cSJohannes Berg #include <linux/utsname.h>
291da177e4SLinus Torvalds #include <asm/unaligned.h>
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds #include <net/bluetooth/bluetooth.h>
321da177e4SLinus Torvalds #include <net/bluetooth/hci_core.h>
33cd82e61cSMarcel Holtmann #include <net/bluetooth/hci_mon.h>
34fa4335d7SJohan Hedberg #include <net/bluetooth/mgmt.h>
35fa4335d7SJohan Hedberg 
36fa4335d7SJohan Hedberg #include "mgmt_util.h"
371da177e4SLinus Torvalds 
38801c1e8dSJohan Hedberg static LIST_HEAD(mgmt_chan_list);
39801c1e8dSJohan Hedberg static DEFINE_MUTEX(mgmt_chan_list_lock);
40801c1e8dSJohan Hedberg 
41cd82e61cSMarcel Holtmann static atomic_t monitor_promisc = ATOMIC_INIT(0);
42cd82e61cSMarcel Holtmann 
431da177e4SLinus Torvalds /* ----- HCI socket interface ----- */
441da177e4SLinus Torvalds 
45863def58SMarcel Holtmann /* Socket info */
46863def58SMarcel Holtmann #define hci_pi(sk) ((struct hci_pinfo *) sk)
47863def58SMarcel Holtmann 
48863def58SMarcel Holtmann struct hci_pinfo {
49863def58SMarcel Holtmann 	struct bt_sock    bt;
50863def58SMarcel Holtmann 	struct hci_dev    *hdev;
51863def58SMarcel Holtmann 	struct hci_filter filter;
52863def58SMarcel Holtmann 	__u32             cmsg_mask;
53863def58SMarcel Holtmann 	unsigned short    channel;
546befc644SMarcel Holtmann 	unsigned long     flags;
55863def58SMarcel Holtmann };
56863def58SMarcel Holtmann 
576befc644SMarcel Holtmann void hci_sock_set_flag(struct sock *sk, int nr)
586befc644SMarcel Holtmann {
596befc644SMarcel Holtmann 	set_bit(nr, &hci_pi(sk)->flags);
606befc644SMarcel Holtmann }
616befc644SMarcel Holtmann 
626befc644SMarcel Holtmann void hci_sock_clear_flag(struct sock *sk, int nr)
636befc644SMarcel Holtmann {
646befc644SMarcel Holtmann 	clear_bit(nr, &hci_pi(sk)->flags);
656befc644SMarcel Holtmann }
666befc644SMarcel Holtmann 
67c85be545SMarcel Holtmann int hci_sock_test_flag(struct sock *sk, int nr)
68c85be545SMarcel Holtmann {
69c85be545SMarcel Holtmann 	return test_bit(nr, &hci_pi(sk)->flags);
70c85be545SMarcel Holtmann }
71c85be545SMarcel Holtmann 
72d0f172b1SJohan Hedberg unsigned short hci_sock_get_channel(struct sock *sk)
73d0f172b1SJohan Hedberg {
74d0f172b1SJohan Hedberg 	return hci_pi(sk)->channel;
75d0f172b1SJohan Hedberg }
76d0f172b1SJohan Hedberg 
779391976aSJiri Slaby static inline int hci_test_bit(int nr, const void *addr)
781da177e4SLinus Torvalds {
799391976aSJiri Slaby 	return *((const __u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
801da177e4SLinus Torvalds }
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds /* Security filter */
833ad254f7SMarcel Holtmann #define HCI_SFLT_MAX_OGF  5
843ad254f7SMarcel Holtmann 
853ad254f7SMarcel Holtmann struct hci_sec_filter {
863ad254f7SMarcel Holtmann 	__u32 type_mask;
873ad254f7SMarcel Holtmann 	__u32 event_mask[2];
883ad254f7SMarcel Holtmann 	__u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
893ad254f7SMarcel Holtmann };
903ad254f7SMarcel Holtmann 
917e67c112SMarcel Holtmann static const struct hci_sec_filter hci_sec_filter = {
921da177e4SLinus Torvalds 	/* Packet types */
931da177e4SLinus Torvalds 	0x10,
941da177e4SLinus Torvalds 	/* Events */
95dd7f5527SMarcel Holtmann 	{ 0x1000d9fe, 0x0000b00c },
961da177e4SLinus Torvalds 	/* Commands */
971da177e4SLinus Torvalds 	{
981da177e4SLinus Torvalds 		{ 0x0 },
991da177e4SLinus Torvalds 		/* OGF_LINK_CTL */
1007c631a67SMarcel Holtmann 		{ 0xbe000006, 0x00000001, 0x00000000, 0x00 },
1011da177e4SLinus Torvalds 		/* OGF_LINK_POLICY */
1027c631a67SMarcel Holtmann 		{ 0x00005200, 0x00000000, 0x00000000, 0x00 },
1031da177e4SLinus Torvalds 		/* OGF_HOST_CTL */
1047c631a67SMarcel Holtmann 		{ 0xaab00200, 0x2b402aaa, 0x05220154, 0x00 },
1051da177e4SLinus Torvalds 		/* OGF_INFO_PARAM */
1067c631a67SMarcel Holtmann 		{ 0x000002be, 0x00000000, 0x00000000, 0x00 },
1071da177e4SLinus Torvalds 		/* OGF_STATUS_PARAM */
1087c631a67SMarcel Holtmann 		{ 0x000000ea, 0x00000000, 0x00000000, 0x00 }
1091da177e4SLinus Torvalds 	}
1101da177e4SLinus Torvalds };
1111da177e4SLinus Torvalds 
1121da177e4SLinus Torvalds static struct bt_sock_list hci_sk_list = {
113d5fb2962SRobert P. J. Day 	.lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock)
1141da177e4SLinus Torvalds };
1151da177e4SLinus Torvalds 
116f81fe64fSMarcel Holtmann static bool is_filtered_packet(struct sock *sk, struct sk_buff *skb)
117f81fe64fSMarcel Holtmann {
118f81fe64fSMarcel Holtmann 	struct hci_filter *flt;
119f81fe64fSMarcel Holtmann 	int flt_type, flt_event;
120f81fe64fSMarcel Holtmann 
121f81fe64fSMarcel Holtmann 	/* Apply filter */
122f81fe64fSMarcel Holtmann 	flt = &hci_pi(sk)->filter;
123f81fe64fSMarcel Holtmann 
124d79f34e3SMarcel Holtmann 	flt_type = hci_skb_pkt_type(skb) & HCI_FLT_TYPE_BITS;
125f81fe64fSMarcel Holtmann 
126f81fe64fSMarcel Holtmann 	if (!test_bit(flt_type, &flt->type_mask))
127f81fe64fSMarcel Holtmann 		return true;
128f81fe64fSMarcel Holtmann 
129f81fe64fSMarcel Holtmann 	/* Extra filter for event packets only */
130d79f34e3SMarcel Holtmann 	if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT)
131f81fe64fSMarcel Holtmann 		return false;
132f81fe64fSMarcel Holtmann 
133f81fe64fSMarcel Holtmann 	flt_event = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
134f81fe64fSMarcel Holtmann 
135f81fe64fSMarcel Holtmann 	if (!hci_test_bit(flt_event, &flt->event_mask))
136f81fe64fSMarcel Holtmann 		return true;
137f81fe64fSMarcel Holtmann 
138f81fe64fSMarcel Holtmann 	/* Check filter only when opcode is set */
139f81fe64fSMarcel Holtmann 	if (!flt->opcode)
140f81fe64fSMarcel Holtmann 		return false;
141f81fe64fSMarcel Holtmann 
142f81fe64fSMarcel Holtmann 	if (flt_event == HCI_EV_CMD_COMPLETE &&
143f81fe64fSMarcel Holtmann 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 3)))
144f81fe64fSMarcel Holtmann 		return true;
145f81fe64fSMarcel Holtmann 
146f81fe64fSMarcel Holtmann 	if (flt_event == HCI_EV_CMD_STATUS &&
147f81fe64fSMarcel Holtmann 	    flt->opcode != get_unaligned((__le16 *)(skb->data + 4)))
148f81fe64fSMarcel Holtmann 		return true;
149f81fe64fSMarcel Holtmann 
150f81fe64fSMarcel Holtmann 	return false;
151f81fe64fSMarcel Holtmann }
152f81fe64fSMarcel Holtmann 
1531da177e4SLinus Torvalds /* Send frame to RAW socket */
154470fe1b5SMarcel Holtmann void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
1551da177e4SLinus Torvalds {
1561da177e4SLinus Torvalds 	struct sock *sk;
157e0edf373SMarcel Holtmann 	struct sk_buff *skb_copy = NULL;
1581da177e4SLinus Torvalds 
1591da177e4SLinus Torvalds 	BT_DBG("hdev %p len %d", hdev, skb->len);
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds 	read_lock(&hci_sk_list.lock);
162470fe1b5SMarcel Holtmann 
163b67bfe0dSSasha Levin 	sk_for_each(sk, &hci_sk_list.head) {
1641da177e4SLinus Torvalds 		struct sk_buff *nskb;
1651da177e4SLinus Torvalds 
1661da177e4SLinus Torvalds 		if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev)
1671da177e4SLinus Torvalds 			continue;
1681da177e4SLinus Torvalds 
1691da177e4SLinus Torvalds 		/* Don't send frame to the socket it came from */
1701da177e4SLinus Torvalds 		if (skb->sk == sk)
1711da177e4SLinus Torvalds 			continue;
1721da177e4SLinus Torvalds 
17323500189SMarcel Holtmann 		if (hci_pi(sk)->channel == HCI_CHANNEL_RAW) {
174d79f34e3SMarcel Holtmann 			if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT &&
175d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
176d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
177d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT)
178bb77543eSMarcel Holtmann 				continue;
179f81fe64fSMarcel Holtmann 			if (is_filtered_packet(sk, skb))
1801da177e4SLinus Torvalds 				continue;
18123500189SMarcel Holtmann 		} else if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
18223500189SMarcel Holtmann 			if (!bt_cb(skb)->incoming)
18323500189SMarcel Holtmann 				continue;
184d79f34e3SMarcel Holtmann 			if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT &&
185d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
186d79f34e3SMarcel Holtmann 			    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT)
18723500189SMarcel Holtmann 				continue;
18823500189SMarcel Holtmann 		} else {
18923500189SMarcel Holtmann 			/* Don't send frame to other channel types */
19023500189SMarcel Holtmann 			continue;
19123500189SMarcel Holtmann 		}
1921da177e4SLinus Torvalds 
193e0edf373SMarcel Holtmann 		if (!skb_copy) {
194e0edf373SMarcel Holtmann 			/* Create a private copy with headroom */
195bad93e9dSOctavian Purdila 			skb_copy = __pskb_copy_fclone(skb, 1, GFP_ATOMIC, true);
196e0edf373SMarcel Holtmann 			if (!skb_copy)
1971da177e4SLinus Torvalds 				continue;
1981da177e4SLinus Torvalds 
1991da177e4SLinus Torvalds 			/* Put type byte before the data */
200d79f34e3SMarcel Holtmann 			memcpy(skb_push(skb_copy, 1), &hci_skb_pkt_type(skb), 1);
201e0edf373SMarcel Holtmann 		}
202e0edf373SMarcel Holtmann 
203e0edf373SMarcel Holtmann 		nskb = skb_clone(skb_copy, GFP_ATOMIC);
204e0edf373SMarcel Holtmann 		if (!nskb)
205e0edf373SMarcel Holtmann 			continue;
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds 		if (sock_queue_rcv_skb(sk, nskb))
2081da177e4SLinus Torvalds 			kfree_skb(nskb);
2091da177e4SLinus Torvalds 	}
210470fe1b5SMarcel Holtmann 
211470fe1b5SMarcel Holtmann 	read_unlock(&hci_sk_list.lock);
212e0edf373SMarcel Holtmann 
213e0edf373SMarcel Holtmann 	kfree_skb(skb_copy);
214470fe1b5SMarcel Holtmann }
215470fe1b5SMarcel Holtmann 
2167129069eSJohan Hedberg /* Send frame to sockets with specific channel */
2177129069eSJohan Hedberg void hci_send_to_channel(unsigned short channel, struct sk_buff *skb,
218c08b1a1dSMarcel Holtmann 			 int flag, struct sock *skip_sk)
219470fe1b5SMarcel Holtmann {
220470fe1b5SMarcel Holtmann 	struct sock *sk;
221470fe1b5SMarcel Holtmann 
2227129069eSJohan Hedberg 	BT_DBG("channel %u len %d", channel, skb->len);
223470fe1b5SMarcel Holtmann 
224470fe1b5SMarcel Holtmann 	read_lock(&hci_sk_list.lock);
225470fe1b5SMarcel Holtmann 
226b67bfe0dSSasha Levin 	sk_for_each(sk, &hci_sk_list.head) {
227470fe1b5SMarcel Holtmann 		struct sk_buff *nskb;
228470fe1b5SMarcel Holtmann 
229c08b1a1dSMarcel Holtmann 		/* Ignore socket without the flag set */
230c85be545SMarcel Holtmann 		if (!hci_sock_test_flag(sk, flag))
231c08b1a1dSMarcel Holtmann 			continue;
232c08b1a1dSMarcel Holtmann 
233470fe1b5SMarcel Holtmann 		/* Skip the original socket */
234470fe1b5SMarcel Holtmann 		if (sk == skip_sk)
235470fe1b5SMarcel Holtmann 			continue;
236470fe1b5SMarcel Holtmann 
237470fe1b5SMarcel Holtmann 		if (sk->sk_state != BT_BOUND)
238470fe1b5SMarcel Holtmann 			continue;
239470fe1b5SMarcel Holtmann 
2407129069eSJohan Hedberg 		if (hci_pi(sk)->channel != channel)
241d7f72f61SMarcel Holtmann 			continue;
242d7f72f61SMarcel Holtmann 
243d7f72f61SMarcel Holtmann 		nskb = skb_clone(skb, GFP_ATOMIC);
244d7f72f61SMarcel Holtmann 		if (!nskb)
245d7f72f61SMarcel Holtmann 			continue;
246d7f72f61SMarcel Holtmann 
247d7f72f61SMarcel Holtmann 		if (sock_queue_rcv_skb(sk, nskb))
248d7f72f61SMarcel Holtmann 			kfree_skb(nskb);
249d7f72f61SMarcel Holtmann 	}
250d7f72f61SMarcel Holtmann 
251d7f72f61SMarcel Holtmann 	read_unlock(&hci_sk_list.lock);
252d7f72f61SMarcel Holtmann }
253d7f72f61SMarcel Holtmann 
254cd82e61cSMarcel Holtmann /* Send frame to monitor socket */
255cd82e61cSMarcel Holtmann void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb)
256cd82e61cSMarcel Holtmann {
257cd82e61cSMarcel Holtmann 	struct sk_buff *skb_copy = NULL;
2582b531294SMarcel Holtmann 	struct hci_mon_hdr *hdr;
259cd82e61cSMarcel Holtmann 	__le16 opcode;
260cd82e61cSMarcel Holtmann 
261cd82e61cSMarcel Holtmann 	if (!atomic_read(&monitor_promisc))
262cd82e61cSMarcel Holtmann 		return;
263cd82e61cSMarcel Holtmann 
264cd82e61cSMarcel Holtmann 	BT_DBG("hdev %p len %d", hdev, skb->len);
265cd82e61cSMarcel Holtmann 
266d79f34e3SMarcel Holtmann 	switch (hci_skb_pkt_type(skb)) {
267cd82e61cSMarcel Holtmann 	case HCI_COMMAND_PKT:
268dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_COMMAND_PKT);
269cd82e61cSMarcel Holtmann 		break;
270cd82e61cSMarcel Holtmann 	case HCI_EVENT_PKT:
271dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_EVENT_PKT);
272cd82e61cSMarcel Holtmann 		break;
273cd82e61cSMarcel Holtmann 	case HCI_ACLDATA_PKT:
274cd82e61cSMarcel Holtmann 		if (bt_cb(skb)->incoming)
275dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_ACL_RX_PKT);
276cd82e61cSMarcel Holtmann 		else
277dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_ACL_TX_PKT);
278cd82e61cSMarcel Holtmann 		break;
279cd82e61cSMarcel Holtmann 	case HCI_SCODATA_PKT:
280cd82e61cSMarcel Holtmann 		if (bt_cb(skb)->incoming)
281dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT);
282cd82e61cSMarcel Holtmann 		else
283dcf4adbfSJoe Perches 			opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT);
284cd82e61cSMarcel Holtmann 		break;
285e875ff84SMarcel Holtmann 	case HCI_DIAG_PKT:
286e875ff84SMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_VENDOR_DIAG);
287e875ff84SMarcel Holtmann 		break;
288cd82e61cSMarcel Holtmann 	default:
289cd82e61cSMarcel Holtmann 		return;
290cd82e61cSMarcel Holtmann 	}
291cd82e61cSMarcel Holtmann 
2922b531294SMarcel Holtmann 	/* Create a private copy with headroom */
2932b531294SMarcel Holtmann 	skb_copy = __pskb_copy_fclone(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC, true);
2942b531294SMarcel Holtmann 	if (!skb_copy)
2952b531294SMarcel Holtmann 		return;
2962b531294SMarcel Holtmann 
2972b531294SMarcel Holtmann 	/* Put header before the data */
2982b531294SMarcel Holtmann 	hdr = (void *)skb_push(skb_copy, HCI_MON_HDR_SIZE);
2992b531294SMarcel Holtmann 	hdr->opcode = opcode;
3002b531294SMarcel Holtmann 	hdr->index = cpu_to_le16(hdev->id);
3012b531294SMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len);
3022b531294SMarcel Holtmann 
303c08b1a1dSMarcel Holtmann 	hci_send_to_channel(HCI_CHANNEL_MONITOR, skb_copy,
304c08b1a1dSMarcel Holtmann 			    HCI_SOCK_TRUSTED, NULL);
305cd82e61cSMarcel Holtmann 	kfree_skb(skb_copy);
306cd82e61cSMarcel Holtmann }
307cd82e61cSMarcel Holtmann 
308cd82e61cSMarcel Holtmann static struct sk_buff *create_monitor_event(struct hci_dev *hdev, int event)
309cd82e61cSMarcel Holtmann {
310cd82e61cSMarcel Holtmann 	struct hci_mon_hdr *hdr;
311cd82e61cSMarcel Holtmann 	struct hci_mon_new_index *ni;
3126c566dd5SMarcel Holtmann 	struct hci_mon_index_info *ii;
313cd82e61cSMarcel Holtmann 	struct sk_buff *skb;
314cd82e61cSMarcel Holtmann 	__le16 opcode;
315cd82e61cSMarcel Holtmann 
316cd82e61cSMarcel Holtmann 	switch (event) {
317cd82e61cSMarcel Holtmann 	case HCI_DEV_REG:
318cd82e61cSMarcel Holtmann 		skb = bt_skb_alloc(HCI_MON_NEW_INDEX_SIZE, GFP_ATOMIC);
319cd82e61cSMarcel Holtmann 		if (!skb)
320cd82e61cSMarcel Holtmann 			return NULL;
321cd82e61cSMarcel Holtmann 
322cd82e61cSMarcel Holtmann 		ni = (void *)skb_put(skb, HCI_MON_NEW_INDEX_SIZE);
323cd82e61cSMarcel Holtmann 		ni->type = hdev->dev_type;
324cd82e61cSMarcel Holtmann 		ni->bus = hdev->bus;
325cd82e61cSMarcel Holtmann 		bacpy(&ni->bdaddr, &hdev->bdaddr);
326cd82e61cSMarcel Holtmann 		memcpy(ni->name, hdev->name, 8);
327cd82e61cSMarcel Holtmann 
328dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_NEW_INDEX);
329cd82e61cSMarcel Holtmann 		break;
330cd82e61cSMarcel Holtmann 
331cd82e61cSMarcel Holtmann 	case HCI_DEV_UNREG:
332cd82e61cSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
333cd82e61cSMarcel Holtmann 		if (!skb)
334cd82e61cSMarcel Holtmann 			return NULL;
335cd82e61cSMarcel Holtmann 
336dcf4adbfSJoe Perches 		opcode = cpu_to_le16(HCI_MON_DEL_INDEX);
337cd82e61cSMarcel Holtmann 		break;
338cd82e61cSMarcel Holtmann 
339e131d74aSMarcel Holtmann 	case HCI_DEV_SETUP:
340e131d74aSMarcel Holtmann 		if (hdev->manufacturer == 0xffff)
341e131d74aSMarcel Holtmann 			return NULL;
342e131d74aSMarcel Holtmann 
343e131d74aSMarcel Holtmann 		/* fall through */
344e131d74aSMarcel Holtmann 
3456c566dd5SMarcel Holtmann 	case HCI_DEV_UP:
3466c566dd5SMarcel Holtmann 		skb = bt_skb_alloc(HCI_MON_INDEX_INFO_SIZE, GFP_ATOMIC);
3476c566dd5SMarcel Holtmann 		if (!skb)
3486c566dd5SMarcel Holtmann 			return NULL;
3496c566dd5SMarcel Holtmann 
3506c566dd5SMarcel Holtmann 		ii = (void *)skb_put(skb, HCI_MON_INDEX_INFO_SIZE);
3516c566dd5SMarcel Holtmann 		bacpy(&ii->bdaddr, &hdev->bdaddr);
3526c566dd5SMarcel Holtmann 		ii->manufacturer = cpu_to_le16(hdev->manufacturer);
3536c566dd5SMarcel Holtmann 
3546c566dd5SMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_INDEX_INFO);
3556c566dd5SMarcel Holtmann 		break;
3566c566dd5SMarcel Holtmann 
35722db3cbcSMarcel Holtmann 	case HCI_DEV_OPEN:
35822db3cbcSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
35922db3cbcSMarcel Holtmann 		if (!skb)
36022db3cbcSMarcel Holtmann 			return NULL;
36122db3cbcSMarcel Holtmann 
36222db3cbcSMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_OPEN_INDEX);
36322db3cbcSMarcel Holtmann 		break;
36422db3cbcSMarcel Holtmann 
36522db3cbcSMarcel Holtmann 	case HCI_DEV_CLOSE:
36622db3cbcSMarcel Holtmann 		skb = bt_skb_alloc(0, GFP_ATOMIC);
36722db3cbcSMarcel Holtmann 		if (!skb)
36822db3cbcSMarcel Holtmann 			return NULL;
36922db3cbcSMarcel Holtmann 
37022db3cbcSMarcel Holtmann 		opcode = cpu_to_le16(HCI_MON_CLOSE_INDEX);
37122db3cbcSMarcel Holtmann 		break;
37222db3cbcSMarcel Holtmann 
373cd82e61cSMarcel Holtmann 	default:
374cd82e61cSMarcel Holtmann 		return NULL;
375cd82e61cSMarcel Holtmann 	}
376cd82e61cSMarcel Holtmann 
377cd82e61cSMarcel Holtmann 	__net_timestamp(skb);
378cd82e61cSMarcel Holtmann 
379cd82e61cSMarcel Holtmann 	hdr = (void *)skb_push(skb, HCI_MON_HDR_SIZE);
380cd82e61cSMarcel Holtmann 	hdr->opcode = opcode;
381cd82e61cSMarcel Holtmann 	hdr->index = cpu_to_le16(hdev->id);
382cd82e61cSMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
383cd82e61cSMarcel Holtmann 
384cd82e61cSMarcel Holtmann 	return skb;
385cd82e61cSMarcel Holtmann }
386cd82e61cSMarcel Holtmann 
387787b306cSJohannes Berg static void __printf(2, 3)
388787b306cSJohannes Berg send_monitor_note(struct sock *sk, const char *fmt, ...)
389dd31506dSMarcel Holtmann {
390787b306cSJohannes Berg 	size_t len;
391dd31506dSMarcel Holtmann 	struct hci_mon_hdr *hdr;
392dd31506dSMarcel Holtmann 	struct sk_buff *skb;
393787b306cSJohannes Berg 	va_list args;
394787b306cSJohannes Berg 
395787b306cSJohannes Berg 	va_start(args, fmt);
396787b306cSJohannes Berg 	len = vsnprintf(NULL, 0, fmt, args);
397787b306cSJohannes Berg 	va_end(args);
398dd31506dSMarcel Holtmann 
399dd31506dSMarcel Holtmann 	skb = bt_skb_alloc(len + 1, GFP_ATOMIC);
400dd31506dSMarcel Holtmann 	if (!skb)
401dd31506dSMarcel Holtmann 		return;
402dd31506dSMarcel Holtmann 
403787b306cSJohannes Berg 	va_start(args, fmt);
404787b306cSJohannes Berg 	vsprintf(skb_put(skb, len), fmt, args);
405787b306cSJohannes Berg 	*skb_put(skb, 1) = 0;
406787b306cSJohannes Berg 	va_end(args);
407dd31506dSMarcel Holtmann 
408dd31506dSMarcel Holtmann 	__net_timestamp(skb);
409dd31506dSMarcel Holtmann 
410dd31506dSMarcel Holtmann 	hdr = (void *)skb_push(skb, HCI_MON_HDR_SIZE);
411dd31506dSMarcel Holtmann 	hdr->opcode = cpu_to_le16(HCI_MON_SYSTEM_NOTE);
412dd31506dSMarcel Holtmann 	hdr->index = cpu_to_le16(HCI_DEV_NONE);
413dd31506dSMarcel Holtmann 	hdr->len = cpu_to_le16(skb->len - HCI_MON_HDR_SIZE);
414dd31506dSMarcel Holtmann 
415dd31506dSMarcel Holtmann 	if (sock_queue_rcv_skb(sk, skb))
416dd31506dSMarcel Holtmann 		kfree_skb(skb);
417dd31506dSMarcel Holtmann }
418dd31506dSMarcel Holtmann 
419cd82e61cSMarcel Holtmann static void send_monitor_replay(struct sock *sk)
420cd82e61cSMarcel Holtmann {
421cd82e61cSMarcel Holtmann 	struct hci_dev *hdev;
422cd82e61cSMarcel Holtmann 
423cd82e61cSMarcel Holtmann 	read_lock(&hci_dev_list_lock);
424cd82e61cSMarcel Holtmann 
425cd82e61cSMarcel Holtmann 	list_for_each_entry(hdev, &hci_dev_list, list) {
426cd82e61cSMarcel Holtmann 		struct sk_buff *skb;
427cd82e61cSMarcel Holtmann 
428cd82e61cSMarcel Holtmann 		skb = create_monitor_event(hdev, HCI_DEV_REG);
429cd82e61cSMarcel Holtmann 		if (!skb)
430cd82e61cSMarcel Holtmann 			continue;
431cd82e61cSMarcel Holtmann 
432cd82e61cSMarcel Holtmann 		if (sock_queue_rcv_skb(sk, skb))
433cd82e61cSMarcel Holtmann 			kfree_skb(skb);
43422db3cbcSMarcel Holtmann 
43522db3cbcSMarcel Holtmann 		if (!test_bit(HCI_RUNNING, &hdev->flags))
43622db3cbcSMarcel Holtmann 			continue;
43722db3cbcSMarcel Holtmann 
43822db3cbcSMarcel Holtmann 		skb = create_monitor_event(hdev, HCI_DEV_OPEN);
43922db3cbcSMarcel Holtmann 		if (!skb)
44022db3cbcSMarcel Holtmann 			continue;
44122db3cbcSMarcel Holtmann 
44222db3cbcSMarcel Holtmann 		if (sock_queue_rcv_skb(sk, skb))
44322db3cbcSMarcel Holtmann 			kfree_skb(skb);
4446c566dd5SMarcel Holtmann 
445e131d74aSMarcel Holtmann 		if (test_bit(HCI_UP, &hdev->flags))
4466c566dd5SMarcel Holtmann 			skb = create_monitor_event(hdev, HCI_DEV_UP);
447e131d74aSMarcel Holtmann 		else if (hci_dev_test_flag(hdev, HCI_SETUP))
448e131d74aSMarcel Holtmann 			skb = create_monitor_event(hdev, HCI_DEV_SETUP);
449e131d74aSMarcel Holtmann 		else
450e131d74aSMarcel Holtmann 			skb = NULL;
4516c566dd5SMarcel Holtmann 
452e131d74aSMarcel Holtmann 		if (skb) {
4536c566dd5SMarcel Holtmann 			if (sock_queue_rcv_skb(sk, skb))
4546c566dd5SMarcel Holtmann 				kfree_skb(skb);
455cd82e61cSMarcel Holtmann 		}
456e131d74aSMarcel Holtmann 	}
457cd82e61cSMarcel Holtmann 
458cd82e61cSMarcel Holtmann 	read_unlock(&hci_dev_list_lock);
459cd82e61cSMarcel Holtmann }
460cd82e61cSMarcel Holtmann 
461040030efSMarcel Holtmann /* Generate internal stack event */
462040030efSMarcel Holtmann static void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
463040030efSMarcel Holtmann {
464040030efSMarcel Holtmann 	struct hci_event_hdr *hdr;
465040030efSMarcel Holtmann 	struct hci_ev_stack_internal *ev;
466040030efSMarcel Holtmann 	struct sk_buff *skb;
467040030efSMarcel Holtmann 
468040030efSMarcel Holtmann 	skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
469040030efSMarcel Holtmann 	if (!skb)
470040030efSMarcel Holtmann 		return;
471040030efSMarcel Holtmann 
472040030efSMarcel Holtmann 	hdr = (void *)skb_put(skb, HCI_EVENT_HDR_SIZE);
473040030efSMarcel Holtmann 	hdr->evt  = HCI_EV_STACK_INTERNAL;
474040030efSMarcel Holtmann 	hdr->plen = sizeof(*ev) + dlen;
475040030efSMarcel Holtmann 
476040030efSMarcel Holtmann 	ev  = (void *)skb_put(skb, sizeof(*ev) + dlen);
477040030efSMarcel Holtmann 	ev->type = type;
478040030efSMarcel Holtmann 	memcpy(ev->data, data, dlen);
479040030efSMarcel Holtmann 
480040030efSMarcel Holtmann 	bt_cb(skb)->incoming = 1;
481040030efSMarcel Holtmann 	__net_timestamp(skb);
482040030efSMarcel Holtmann 
483d79f34e3SMarcel Holtmann 	hci_skb_pkt_type(skb) = HCI_EVENT_PKT;
484040030efSMarcel Holtmann 	hci_send_to_sock(hdev, skb);
485040030efSMarcel Holtmann 	kfree_skb(skb);
486040030efSMarcel Holtmann }
487040030efSMarcel Holtmann 
488040030efSMarcel Holtmann void hci_sock_dev_event(struct hci_dev *hdev, int event)
489040030efSMarcel Holtmann {
490040030efSMarcel Holtmann 	BT_DBG("hdev %s event %d", hdev->name, event);
491040030efSMarcel Holtmann 
492cd82e61cSMarcel Holtmann 	if (atomic_read(&monitor_promisc)) {
493cd82e61cSMarcel Holtmann 		struct sk_buff *skb;
494cd82e61cSMarcel Holtmann 
495ed1b28a4SMarcel Holtmann 		/* Send event to monitor */
496cd82e61cSMarcel Holtmann 		skb = create_monitor_event(hdev, event);
497cd82e61cSMarcel Holtmann 		if (skb) {
498c08b1a1dSMarcel Holtmann 			hci_send_to_channel(HCI_CHANNEL_MONITOR, skb,
499c08b1a1dSMarcel Holtmann 					    HCI_SOCK_TRUSTED, NULL);
500cd82e61cSMarcel Holtmann 			kfree_skb(skb);
501cd82e61cSMarcel Holtmann 		}
502cd82e61cSMarcel Holtmann 	}
503cd82e61cSMarcel Holtmann 
504ed1b28a4SMarcel Holtmann 	if (event <= HCI_DEV_DOWN) {
505ed1b28a4SMarcel Holtmann 		struct hci_ev_si_device ev;
506ed1b28a4SMarcel Holtmann 
507040030efSMarcel Holtmann 		/* Send event to sockets */
508040030efSMarcel Holtmann 		ev.event  = event;
509040030efSMarcel Holtmann 		ev.dev_id = hdev->id;
510040030efSMarcel Holtmann 		hci_si_event(NULL, HCI_EV_SI_DEVICE, sizeof(ev), &ev);
511ed1b28a4SMarcel Holtmann 	}
512040030efSMarcel Holtmann 
513040030efSMarcel Holtmann 	if (event == HCI_DEV_UNREG) {
514040030efSMarcel Holtmann 		struct sock *sk;
515040030efSMarcel Holtmann 
516040030efSMarcel Holtmann 		/* Detach sockets from device */
517040030efSMarcel Holtmann 		read_lock(&hci_sk_list.lock);
518b67bfe0dSSasha Levin 		sk_for_each(sk, &hci_sk_list.head) {
519040030efSMarcel Holtmann 			bh_lock_sock_nested(sk);
520040030efSMarcel Holtmann 			if (hci_pi(sk)->hdev == hdev) {
521040030efSMarcel Holtmann 				hci_pi(sk)->hdev = NULL;
522040030efSMarcel Holtmann 				sk->sk_err = EPIPE;
523040030efSMarcel Holtmann 				sk->sk_state = BT_OPEN;
524040030efSMarcel Holtmann 				sk->sk_state_change(sk);
525040030efSMarcel Holtmann 
526040030efSMarcel Holtmann 				hci_dev_put(hdev);
527040030efSMarcel Holtmann 			}
528040030efSMarcel Holtmann 			bh_unlock_sock(sk);
529040030efSMarcel Holtmann 		}
530040030efSMarcel Holtmann 		read_unlock(&hci_sk_list.lock);
531040030efSMarcel Holtmann 	}
532040030efSMarcel Holtmann }
533040030efSMarcel Holtmann 
534801c1e8dSJohan Hedberg static struct hci_mgmt_chan *__hci_mgmt_chan_find(unsigned short channel)
535801c1e8dSJohan Hedberg {
536801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *c;
537801c1e8dSJohan Hedberg 
538801c1e8dSJohan Hedberg 	list_for_each_entry(c, &mgmt_chan_list, list) {
539801c1e8dSJohan Hedberg 		if (c->channel == channel)
540801c1e8dSJohan Hedberg 			return c;
541801c1e8dSJohan Hedberg 	}
542801c1e8dSJohan Hedberg 
543801c1e8dSJohan Hedberg 	return NULL;
544801c1e8dSJohan Hedberg }
545801c1e8dSJohan Hedberg 
546801c1e8dSJohan Hedberg static struct hci_mgmt_chan *hci_mgmt_chan_find(unsigned short channel)
547801c1e8dSJohan Hedberg {
548801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *c;
549801c1e8dSJohan Hedberg 
550801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
551801c1e8dSJohan Hedberg 	c = __hci_mgmt_chan_find(channel);
552801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
553801c1e8dSJohan Hedberg 
554801c1e8dSJohan Hedberg 	return c;
555801c1e8dSJohan Hedberg }
556801c1e8dSJohan Hedberg 
557801c1e8dSJohan Hedberg int hci_mgmt_chan_register(struct hci_mgmt_chan *c)
558801c1e8dSJohan Hedberg {
559801c1e8dSJohan Hedberg 	if (c->channel < HCI_CHANNEL_CONTROL)
560801c1e8dSJohan Hedberg 		return -EINVAL;
561801c1e8dSJohan Hedberg 
562801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
563801c1e8dSJohan Hedberg 	if (__hci_mgmt_chan_find(c->channel)) {
564801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
565801c1e8dSJohan Hedberg 		return -EALREADY;
566801c1e8dSJohan Hedberg 	}
567801c1e8dSJohan Hedberg 
568801c1e8dSJohan Hedberg 	list_add_tail(&c->list, &mgmt_chan_list);
569801c1e8dSJohan Hedberg 
570801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
571801c1e8dSJohan Hedberg 
572801c1e8dSJohan Hedberg 	return 0;
573801c1e8dSJohan Hedberg }
574801c1e8dSJohan Hedberg EXPORT_SYMBOL(hci_mgmt_chan_register);
575801c1e8dSJohan Hedberg 
576801c1e8dSJohan Hedberg void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c)
577801c1e8dSJohan Hedberg {
578801c1e8dSJohan Hedberg 	mutex_lock(&mgmt_chan_list_lock);
579801c1e8dSJohan Hedberg 	list_del(&c->list);
580801c1e8dSJohan Hedberg 	mutex_unlock(&mgmt_chan_list_lock);
581801c1e8dSJohan Hedberg }
582801c1e8dSJohan Hedberg EXPORT_SYMBOL(hci_mgmt_chan_unregister);
583801c1e8dSJohan Hedberg 
5841da177e4SLinus Torvalds static int hci_sock_release(struct socket *sock)
5851da177e4SLinus Torvalds {
5861da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
5877b005bd3SMarcel Holtmann 	struct hci_dev *hdev;
5881da177e4SLinus Torvalds 
5891da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
5901da177e4SLinus Torvalds 
5911da177e4SLinus Torvalds 	if (!sk)
5921da177e4SLinus Torvalds 		return 0;
5931da177e4SLinus Torvalds 
5947b005bd3SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
5957b005bd3SMarcel Holtmann 
596cd82e61cSMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_MONITOR)
597cd82e61cSMarcel Holtmann 		atomic_dec(&monitor_promisc);
598cd82e61cSMarcel Holtmann 
5991da177e4SLinus Torvalds 	bt_sock_unlink(&hci_sk_list, sk);
6001da177e4SLinus Torvalds 
6011da177e4SLinus Torvalds 	if (hdev) {
60223500189SMarcel Holtmann 		if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
6036b3cc1dbSSimon Fels 			/* When releasing an user channel exclusive access,
6046b3cc1dbSSimon Fels 			 * call hci_dev_do_close directly instead of calling
6056b3cc1dbSSimon Fels 			 * hci_dev_close to ensure the exclusive access will
6066b3cc1dbSSimon Fels 			 * be released and the controller brought back down.
6076b3cc1dbSSimon Fels 			 *
6086b3cc1dbSSimon Fels 			 * The checking of HCI_AUTO_OFF is not needed in this
6096b3cc1dbSSimon Fels 			 * case since it will have been cleared already when
6106b3cc1dbSSimon Fels 			 * opening the user channel.
6116b3cc1dbSSimon Fels 			 */
6126b3cc1dbSSimon Fels 			hci_dev_do_close(hdev);
6139380f9eaSLoic Poulain 			hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
6149380f9eaSLoic Poulain 			mgmt_index_added(hdev);
61523500189SMarcel Holtmann 		}
61623500189SMarcel Holtmann 
6171da177e4SLinus Torvalds 		atomic_dec(&hdev->promisc);
6181da177e4SLinus Torvalds 		hci_dev_put(hdev);
6191da177e4SLinus Torvalds 	}
6201da177e4SLinus Torvalds 
6211da177e4SLinus Torvalds 	sock_orphan(sk);
6221da177e4SLinus Torvalds 
6231da177e4SLinus Torvalds 	skb_queue_purge(&sk->sk_receive_queue);
6241da177e4SLinus Torvalds 	skb_queue_purge(&sk->sk_write_queue);
6251da177e4SLinus Torvalds 
6261da177e4SLinus Torvalds 	sock_put(sk);
6271da177e4SLinus Torvalds 	return 0;
6281da177e4SLinus Torvalds }
6291da177e4SLinus Torvalds 
630b2a66aadSAntti Julku static int hci_sock_blacklist_add(struct hci_dev *hdev, void __user *arg)
631f0358568SJohan Hedberg {
632f0358568SJohan Hedberg 	bdaddr_t bdaddr;
6335e762444SAntti Julku 	int err;
634f0358568SJohan Hedberg 
635f0358568SJohan Hedberg 	if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
636f0358568SJohan Hedberg 		return -EFAULT;
637f0358568SJohan Hedberg 
63809fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6395e762444SAntti Julku 
640dcc36c16SJohan Hedberg 	err = hci_bdaddr_list_add(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
6415e762444SAntti Julku 
64209fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6435e762444SAntti Julku 
6445e762444SAntti Julku 	return err;
645f0358568SJohan Hedberg }
646f0358568SJohan Hedberg 
647b2a66aadSAntti Julku static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg)
648f0358568SJohan Hedberg {
649f0358568SJohan Hedberg 	bdaddr_t bdaddr;
6505e762444SAntti Julku 	int err;
651f0358568SJohan Hedberg 
652f0358568SJohan Hedberg 	if (copy_from_user(&bdaddr, arg, sizeof(bdaddr)))
653f0358568SJohan Hedberg 		return -EFAULT;
654f0358568SJohan Hedberg 
65509fd0de5SGustavo F. Padovan 	hci_dev_lock(hdev);
6565e762444SAntti Julku 
657dcc36c16SJohan Hedberg 	err = hci_bdaddr_list_del(&hdev->blacklist, &bdaddr, BDADDR_BREDR);
6585e762444SAntti Julku 
65909fd0de5SGustavo F. Padovan 	hci_dev_unlock(hdev);
6605e762444SAntti Julku 
6615e762444SAntti Julku 	return err;
662f0358568SJohan Hedberg }
663f0358568SJohan Hedberg 
6641da177e4SLinus Torvalds /* Ioctls that require bound socket */
6656039aa73SGustavo Padovan static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd,
6666039aa73SGustavo Padovan 				unsigned long arg)
6671da177e4SLinus Torvalds {
6681da177e4SLinus Torvalds 	struct hci_dev *hdev = hci_pi(sk)->hdev;
6691da177e4SLinus Torvalds 
6701da177e4SLinus Torvalds 	if (!hdev)
6711da177e4SLinus Torvalds 		return -EBADFD;
6721da177e4SLinus Torvalds 
673d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL))
6740736cfa8SMarcel Holtmann 		return -EBUSY;
6750736cfa8SMarcel Holtmann 
676d7a5a11dSMarcel Holtmann 	if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED))
677fee746b0SMarcel Holtmann 		return -EOPNOTSUPP;
678fee746b0SMarcel Holtmann 
679ca8bee5dSMarcel Holtmann 	if (hdev->dev_type != HCI_PRIMARY)
6805b69bef5SMarcel Holtmann 		return -EOPNOTSUPP;
6815b69bef5SMarcel Holtmann 
6821da177e4SLinus Torvalds 	switch (cmd) {
6831da177e4SLinus Torvalds 	case HCISETRAW:
6841da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
685bf5b30b8SZhao Hongjiang 			return -EPERM;
686db596681SMarcel Holtmann 		return -EOPNOTSUPP;
6871da177e4SLinus Torvalds 
6881da177e4SLinus Torvalds 	case HCIGETCONNINFO:
6891da177e4SLinus Torvalds 		return hci_get_conn_info(hdev, (void __user *)arg);
6901da177e4SLinus Torvalds 
69140be492fSMarcel Holtmann 	case HCIGETAUTHINFO:
69240be492fSMarcel Holtmann 		return hci_get_auth_info(hdev, (void __user *)arg);
69340be492fSMarcel Holtmann 
694f0358568SJohan Hedberg 	case HCIBLOCKADDR:
695f0358568SJohan Hedberg 		if (!capable(CAP_NET_ADMIN))
696bf5b30b8SZhao Hongjiang 			return -EPERM;
697b2a66aadSAntti Julku 		return hci_sock_blacklist_add(hdev, (void __user *)arg);
698f0358568SJohan Hedberg 
699f0358568SJohan Hedberg 	case HCIUNBLOCKADDR:
700f0358568SJohan Hedberg 		if (!capable(CAP_NET_ADMIN))
701bf5b30b8SZhao Hongjiang 			return -EPERM;
702b2a66aadSAntti Julku 		return hci_sock_blacklist_del(hdev, (void __user *)arg);
7030736cfa8SMarcel Holtmann 	}
704f0358568SJohan Hedberg 
705324d36edSMarcel Holtmann 	return -ENOIOCTLCMD;
7061da177e4SLinus Torvalds }
7071da177e4SLinus Torvalds 
7088fc9ced3SGustavo Padovan static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
7098fc9ced3SGustavo Padovan 			  unsigned long arg)
7101da177e4SLinus Torvalds {
7111da177e4SLinus Torvalds 	void __user *argp = (void __user *)arg;
7120736cfa8SMarcel Holtmann 	struct sock *sk = sock->sk;
7131da177e4SLinus Torvalds 	int err;
7141da177e4SLinus Torvalds 
7151da177e4SLinus Torvalds 	BT_DBG("cmd %x arg %lx", cmd, arg);
7161da177e4SLinus Torvalds 
717c1c4f956SMarcel Holtmann 	lock_sock(sk);
718c1c4f956SMarcel Holtmann 
719c1c4f956SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
720c1c4f956SMarcel Holtmann 		err = -EBADFD;
721c1c4f956SMarcel Holtmann 		goto done;
722c1c4f956SMarcel Holtmann 	}
723c1c4f956SMarcel Holtmann 
724c1c4f956SMarcel Holtmann 	release_sock(sk);
725c1c4f956SMarcel Holtmann 
7261da177e4SLinus Torvalds 	switch (cmd) {
7271da177e4SLinus Torvalds 	case HCIGETDEVLIST:
7281da177e4SLinus Torvalds 		return hci_get_dev_list(argp);
7291da177e4SLinus Torvalds 
7301da177e4SLinus Torvalds 	case HCIGETDEVINFO:
7311da177e4SLinus Torvalds 		return hci_get_dev_info(argp);
7321da177e4SLinus Torvalds 
7331da177e4SLinus Torvalds 	case HCIGETCONNLIST:
7341da177e4SLinus Torvalds 		return hci_get_conn_list(argp);
7351da177e4SLinus Torvalds 
7361da177e4SLinus Torvalds 	case HCIDEVUP:
7371da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
738bf5b30b8SZhao Hongjiang 			return -EPERM;
7391da177e4SLinus Torvalds 		return hci_dev_open(arg);
7401da177e4SLinus Torvalds 
7411da177e4SLinus Torvalds 	case HCIDEVDOWN:
7421da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
743bf5b30b8SZhao Hongjiang 			return -EPERM;
7441da177e4SLinus Torvalds 		return hci_dev_close(arg);
7451da177e4SLinus Torvalds 
7461da177e4SLinus Torvalds 	case HCIDEVRESET:
7471da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
748bf5b30b8SZhao Hongjiang 			return -EPERM;
7491da177e4SLinus Torvalds 		return hci_dev_reset(arg);
7501da177e4SLinus Torvalds 
7511da177e4SLinus Torvalds 	case HCIDEVRESTAT:
7521da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
753bf5b30b8SZhao Hongjiang 			return -EPERM;
7541da177e4SLinus Torvalds 		return hci_dev_reset_stat(arg);
7551da177e4SLinus Torvalds 
7561da177e4SLinus Torvalds 	case HCISETSCAN:
7571da177e4SLinus Torvalds 	case HCISETAUTH:
7581da177e4SLinus Torvalds 	case HCISETENCRYPT:
7591da177e4SLinus Torvalds 	case HCISETPTYPE:
7601da177e4SLinus Torvalds 	case HCISETLINKPOL:
7611da177e4SLinus Torvalds 	case HCISETLINKMODE:
7621da177e4SLinus Torvalds 	case HCISETACLMTU:
7631da177e4SLinus Torvalds 	case HCISETSCOMTU:
7641da177e4SLinus Torvalds 		if (!capable(CAP_NET_ADMIN))
765bf5b30b8SZhao Hongjiang 			return -EPERM;
7661da177e4SLinus Torvalds 		return hci_dev_cmd(cmd, argp);
7671da177e4SLinus Torvalds 
7681da177e4SLinus Torvalds 	case HCIINQUIRY:
7691da177e4SLinus Torvalds 		return hci_inquiry(argp);
770c1c4f956SMarcel Holtmann 	}
7711da177e4SLinus Torvalds 
7721da177e4SLinus Torvalds 	lock_sock(sk);
773c1c4f956SMarcel Holtmann 
7741da177e4SLinus Torvalds 	err = hci_sock_bound_ioctl(sk, cmd, arg);
775c1c4f956SMarcel Holtmann 
776c1c4f956SMarcel Holtmann done:
7771da177e4SLinus Torvalds 	release_sock(sk);
7781da177e4SLinus Torvalds 	return err;
7791da177e4SLinus Torvalds }
7801da177e4SLinus Torvalds 
7818fc9ced3SGustavo Padovan static int hci_sock_bind(struct socket *sock, struct sockaddr *addr,
7828fc9ced3SGustavo Padovan 			 int addr_len)
7831da177e4SLinus Torvalds {
7840381101fSJohan Hedberg 	struct sockaddr_hci haddr;
7851da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
7861da177e4SLinus Torvalds 	struct hci_dev *hdev = NULL;
7870381101fSJohan Hedberg 	int len, err = 0;
7881da177e4SLinus Torvalds 
7891da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
7901da177e4SLinus Torvalds 
7910381101fSJohan Hedberg 	if (!addr)
7920381101fSJohan Hedberg 		return -EINVAL;
7930381101fSJohan Hedberg 
7940381101fSJohan Hedberg 	memset(&haddr, 0, sizeof(haddr));
7950381101fSJohan Hedberg 	len = min_t(unsigned int, sizeof(haddr), addr_len);
7960381101fSJohan Hedberg 	memcpy(&haddr, addr, len);
7970381101fSJohan Hedberg 
7980381101fSJohan Hedberg 	if (haddr.hci_family != AF_BLUETOOTH)
7990381101fSJohan Hedberg 		return -EINVAL;
8000381101fSJohan Hedberg 
8011da177e4SLinus Torvalds 	lock_sock(sk);
8021da177e4SLinus Torvalds 
8037cc2ade2SMarcel Holtmann 	if (sk->sk_state == BT_BOUND) {
8047cc2ade2SMarcel Holtmann 		err = -EALREADY;
8057cc2ade2SMarcel Holtmann 		goto done;
8067cc2ade2SMarcel Holtmann 	}
8077cc2ade2SMarcel Holtmann 
8087cc2ade2SMarcel Holtmann 	switch (haddr.hci_channel) {
8097cc2ade2SMarcel Holtmann 	case HCI_CHANNEL_RAW:
8107cc2ade2SMarcel Holtmann 		if (hci_pi(sk)->hdev) {
8111da177e4SLinus Torvalds 			err = -EALREADY;
8121da177e4SLinus Torvalds 			goto done;
8131da177e4SLinus Torvalds 		}
8141da177e4SLinus Torvalds 
8150381101fSJohan Hedberg 		if (haddr.hci_dev != HCI_DEV_NONE) {
8160381101fSJohan Hedberg 			hdev = hci_dev_get(haddr.hci_dev);
81770f23020SAndrei Emeltchenko 			if (!hdev) {
8181da177e4SLinus Torvalds 				err = -ENODEV;
8191da177e4SLinus Torvalds 				goto done;
8201da177e4SLinus Torvalds 			}
8211da177e4SLinus Torvalds 
8221da177e4SLinus Torvalds 			atomic_inc(&hdev->promisc);
8231da177e4SLinus Torvalds 		}
8241da177e4SLinus Torvalds 
8251da177e4SLinus Torvalds 		hci_pi(sk)->hdev = hdev;
8267cc2ade2SMarcel Holtmann 		break;
8277cc2ade2SMarcel Holtmann 
82823500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
82923500189SMarcel Holtmann 		if (hci_pi(sk)->hdev) {
83023500189SMarcel Holtmann 			err = -EALREADY;
83123500189SMarcel Holtmann 			goto done;
83223500189SMarcel Holtmann 		}
83323500189SMarcel Holtmann 
83423500189SMarcel Holtmann 		if (haddr.hci_dev == HCI_DEV_NONE) {
83523500189SMarcel Holtmann 			err = -EINVAL;
83623500189SMarcel Holtmann 			goto done;
83723500189SMarcel Holtmann 		}
83823500189SMarcel Holtmann 
83910a8b86fSMarcel Holtmann 		if (!capable(CAP_NET_ADMIN)) {
84023500189SMarcel Holtmann 			err = -EPERM;
84123500189SMarcel Holtmann 			goto done;
84223500189SMarcel Holtmann 		}
84323500189SMarcel Holtmann 
84423500189SMarcel Holtmann 		hdev = hci_dev_get(haddr.hci_dev);
84523500189SMarcel Holtmann 		if (!hdev) {
84623500189SMarcel Holtmann 			err = -ENODEV;
84723500189SMarcel Holtmann 			goto done;
84823500189SMarcel Holtmann 		}
84923500189SMarcel Holtmann 
850781f899fSMarcel Holtmann 		if (test_bit(HCI_INIT, &hdev->flags) ||
851d7a5a11dSMarcel Holtmann 		    hci_dev_test_flag(hdev, HCI_SETUP) ||
852781f899fSMarcel Holtmann 		    hci_dev_test_flag(hdev, HCI_CONFIG) ||
853781f899fSMarcel Holtmann 		    (!hci_dev_test_flag(hdev, HCI_AUTO_OFF) &&
854781f899fSMarcel Holtmann 		     test_bit(HCI_UP, &hdev->flags))) {
85523500189SMarcel Holtmann 			err = -EBUSY;
85623500189SMarcel Holtmann 			hci_dev_put(hdev);
85723500189SMarcel Holtmann 			goto done;
85823500189SMarcel Holtmann 		}
85923500189SMarcel Holtmann 
860238be788SMarcel Holtmann 		if (hci_dev_test_and_set_flag(hdev, HCI_USER_CHANNEL)) {
86123500189SMarcel Holtmann 			err = -EUSERS;
86223500189SMarcel Holtmann 			hci_dev_put(hdev);
86323500189SMarcel Holtmann 			goto done;
86423500189SMarcel Holtmann 		}
86523500189SMarcel Holtmann 
86623500189SMarcel Holtmann 		mgmt_index_removed(hdev);
86723500189SMarcel Holtmann 
86823500189SMarcel Holtmann 		err = hci_dev_open(hdev->id);
86923500189SMarcel Holtmann 		if (err) {
870781f899fSMarcel Holtmann 			if (err == -EALREADY) {
871781f899fSMarcel Holtmann 				/* In case the transport is already up and
872781f899fSMarcel Holtmann 				 * running, clear the error here.
873781f899fSMarcel Holtmann 				 *
874781f899fSMarcel Holtmann 				 * This can happen when opening an user
875781f899fSMarcel Holtmann 				 * channel and HCI_AUTO_OFF grace period
876781f899fSMarcel Holtmann 				 * is still active.
877781f899fSMarcel Holtmann 				 */
878781f899fSMarcel Holtmann 				err = 0;
879781f899fSMarcel Holtmann 			} else {
880a358dc11SMarcel Holtmann 				hci_dev_clear_flag(hdev, HCI_USER_CHANNEL);
881c6521401SMarcel Holtmann 				mgmt_index_added(hdev);
88223500189SMarcel Holtmann 				hci_dev_put(hdev);
88323500189SMarcel Holtmann 				goto done;
88423500189SMarcel Holtmann 			}
885781f899fSMarcel Holtmann 		}
88623500189SMarcel Holtmann 
88723500189SMarcel Holtmann 		atomic_inc(&hdev->promisc);
88823500189SMarcel Holtmann 
88923500189SMarcel Holtmann 		hci_pi(sk)->hdev = hdev;
89023500189SMarcel Holtmann 		break;
89123500189SMarcel Holtmann 
892cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
893cd82e61cSMarcel Holtmann 		if (haddr.hci_dev != HCI_DEV_NONE) {
894cd82e61cSMarcel Holtmann 			err = -EINVAL;
895cd82e61cSMarcel Holtmann 			goto done;
896cd82e61cSMarcel Holtmann 		}
897cd82e61cSMarcel Holtmann 
898cd82e61cSMarcel Holtmann 		if (!capable(CAP_NET_RAW)) {
899cd82e61cSMarcel Holtmann 			err = -EPERM;
900cd82e61cSMarcel Holtmann 			goto done;
901cd82e61cSMarcel Holtmann 		}
902cd82e61cSMarcel Holtmann 
90350ebc055SMarcel Holtmann 		/* The monitor interface is restricted to CAP_NET_RAW
90450ebc055SMarcel Holtmann 		 * capabilities and with that implicitly trusted.
90550ebc055SMarcel Holtmann 		 */
90650ebc055SMarcel Holtmann 		hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
90750ebc055SMarcel Holtmann 
908787b306cSJohannes Berg 		send_monitor_note(sk, "Linux version %s (%s)",
909787b306cSJohannes Berg 				  init_utsname()->release,
910787b306cSJohannes Berg 				  init_utsname()->machine);
911787b306cSJohannes Berg 		send_monitor_note(sk, "Bluetooth subsystem version %s",
912dd31506dSMarcel Holtmann 				  BT_SUBSYS_VERSION);
913cd82e61cSMarcel Holtmann 		send_monitor_replay(sk);
914cd82e61cSMarcel Holtmann 
915cd82e61cSMarcel Holtmann 		atomic_inc(&monitor_promisc);
916cd82e61cSMarcel Holtmann 		break;
917cd82e61cSMarcel Holtmann 
918ac714949SMarcel Holtmann 	case HCI_CHANNEL_LOGGING:
919ac714949SMarcel Holtmann 		if (haddr.hci_dev != HCI_DEV_NONE) {
920ac714949SMarcel Holtmann 			err = -EINVAL;
921ac714949SMarcel Holtmann 			goto done;
922ac714949SMarcel Holtmann 		}
923ac714949SMarcel Holtmann 
924ac714949SMarcel Holtmann 		if (!capable(CAP_NET_ADMIN)) {
925ac714949SMarcel Holtmann 			err = -EPERM;
926ac714949SMarcel Holtmann 			goto done;
927ac714949SMarcel Holtmann 		}
928ac714949SMarcel Holtmann 		break;
929ac714949SMarcel Holtmann 
9307cc2ade2SMarcel Holtmann 	default:
931801c1e8dSJohan Hedberg 		if (!hci_mgmt_chan_find(haddr.hci_channel)) {
9327cc2ade2SMarcel Holtmann 			err = -EINVAL;
9337cc2ade2SMarcel Holtmann 			goto done;
9347cc2ade2SMarcel Holtmann 		}
9357cc2ade2SMarcel Holtmann 
936801c1e8dSJohan Hedberg 		if (haddr.hci_dev != HCI_DEV_NONE) {
937801c1e8dSJohan Hedberg 			err = -EINVAL;
938801c1e8dSJohan Hedberg 			goto done;
939801c1e8dSJohan Hedberg 		}
940801c1e8dSJohan Hedberg 
9411195fbb8SMarcel Holtmann 		/* Users with CAP_NET_ADMIN capabilities are allowed
9421195fbb8SMarcel Holtmann 		 * access to all management commands and events. For
9431195fbb8SMarcel Holtmann 		 * untrusted users the interface is restricted and
9441195fbb8SMarcel Holtmann 		 * also only untrusted events are sent.
94550ebc055SMarcel Holtmann 		 */
9461195fbb8SMarcel Holtmann 		if (capable(CAP_NET_ADMIN))
94750ebc055SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
94850ebc055SMarcel Holtmann 
949f9207338SMarcel Holtmann 		/* At the moment the index and unconfigured index events
950f9207338SMarcel Holtmann 		 * are enabled unconditionally. Setting them on each
951f9207338SMarcel Holtmann 		 * socket when binding keeps this functionality. They
952f9207338SMarcel Holtmann 		 * however might be cleared later and then sending of these
953f9207338SMarcel Holtmann 		 * events will be disabled, but that is then intentional.
954f6b7712eSMarcel Holtmann 		 *
955f6b7712eSMarcel Holtmann 		 * This also enables generic events that are safe to be
956f6b7712eSMarcel Holtmann 		 * received by untrusted users. Example for such events
957f6b7712eSMarcel Holtmann 		 * are changes to settings, class of device, name etc.
958f9207338SMarcel Holtmann 		 */
959f9207338SMarcel Holtmann 		if (haddr.hci_channel == HCI_CHANNEL_CONTROL) {
960f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_INDEX_EVENTS);
961f9207338SMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_UNCONF_INDEX_EVENTS);
962f6b7712eSMarcel Holtmann 			hci_sock_set_flag(sk, HCI_MGMT_GENERIC_EVENTS);
963f9207338SMarcel Holtmann 		}
964801c1e8dSJohan Hedberg 		break;
965801c1e8dSJohan Hedberg 	}
966801c1e8dSJohan Hedberg 
9677cc2ade2SMarcel Holtmann 
9687cc2ade2SMarcel Holtmann 	hci_pi(sk)->channel = haddr.hci_channel;
9691da177e4SLinus Torvalds 	sk->sk_state = BT_BOUND;
9701da177e4SLinus Torvalds 
9711da177e4SLinus Torvalds done:
9721da177e4SLinus Torvalds 	release_sock(sk);
9731da177e4SLinus Torvalds 	return err;
9741da177e4SLinus Torvalds }
9751da177e4SLinus Torvalds 
9768fc9ced3SGustavo Padovan static int hci_sock_getname(struct socket *sock, struct sockaddr *addr,
9778fc9ced3SGustavo Padovan 			    int *addr_len, int peer)
9781da177e4SLinus Torvalds {
9791da177e4SLinus Torvalds 	struct sockaddr_hci *haddr = (struct sockaddr_hci *)addr;
9801da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
9819d4b68b2SMarcel Holtmann 	struct hci_dev *hdev;
9829d4b68b2SMarcel Holtmann 	int err = 0;
9831da177e4SLinus Torvalds 
9841da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
9851da177e4SLinus Torvalds 
98606f43cbcSMarcel Holtmann 	if (peer)
98706f43cbcSMarcel Holtmann 		return -EOPNOTSUPP;
98806f43cbcSMarcel Holtmann 
9891da177e4SLinus Torvalds 	lock_sock(sk);
9901da177e4SLinus Torvalds 
9919d4b68b2SMarcel Holtmann 	hdev = hci_pi(sk)->hdev;
9929d4b68b2SMarcel Holtmann 	if (!hdev) {
9939d4b68b2SMarcel Holtmann 		err = -EBADFD;
9949d4b68b2SMarcel Holtmann 		goto done;
9959d4b68b2SMarcel Holtmann 	}
9969d4b68b2SMarcel Holtmann 
9971da177e4SLinus Torvalds 	*addr_len = sizeof(*haddr);
9981da177e4SLinus Torvalds 	haddr->hci_family = AF_BLUETOOTH;
9997b005bd3SMarcel Holtmann 	haddr->hci_dev    = hdev->id;
10009d4b68b2SMarcel Holtmann 	haddr->hci_channel= hci_pi(sk)->channel;
10011da177e4SLinus Torvalds 
10029d4b68b2SMarcel Holtmann done:
10031da177e4SLinus Torvalds 	release_sock(sk);
10049d4b68b2SMarcel Holtmann 	return err;
10051da177e4SLinus Torvalds }
10061da177e4SLinus Torvalds 
10076039aa73SGustavo Padovan static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg,
10086039aa73SGustavo Padovan 			  struct sk_buff *skb)
10091da177e4SLinus Torvalds {
10101da177e4SLinus Torvalds 	__u32 mask = hci_pi(sk)->cmsg_mask;
10111da177e4SLinus Torvalds 
10120d48d939SMarcel Holtmann 	if (mask & HCI_CMSG_DIR) {
10130d48d939SMarcel Holtmann 		int incoming = bt_cb(skb)->incoming;
10148fc9ced3SGustavo Padovan 		put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming),
10158fc9ced3SGustavo Padovan 			 &incoming);
10160d48d939SMarcel Holtmann 	}
10171da177e4SLinus Torvalds 
1018a61bbcf2SPatrick McHardy 	if (mask & HCI_CMSG_TSTAMP) {
1019f6e623a6SJohann Felix Soden #ifdef CONFIG_COMPAT
1020f6e623a6SJohann Felix Soden 		struct compat_timeval ctv;
1021f6e623a6SJohann Felix Soden #endif
1022a61bbcf2SPatrick McHardy 		struct timeval tv;
1023767c5eb5SMarcel Holtmann 		void *data;
1024767c5eb5SMarcel Holtmann 		int len;
1025a61bbcf2SPatrick McHardy 
1026a61bbcf2SPatrick McHardy 		skb_get_timestamp(skb, &tv);
1027767c5eb5SMarcel Holtmann 
10281da97f83SDavid S. Miller 		data = &tv;
10291da97f83SDavid S. Miller 		len = sizeof(tv);
10301da97f83SDavid S. Miller #ifdef CONFIG_COMPAT
1031da88cea1SH. J. Lu 		if (!COMPAT_USE_64BIT_TIME &&
1032da88cea1SH. J. Lu 		    (msg->msg_flags & MSG_CMSG_COMPAT)) {
1033767c5eb5SMarcel Holtmann 			ctv.tv_sec = tv.tv_sec;
1034767c5eb5SMarcel Holtmann 			ctv.tv_usec = tv.tv_usec;
1035767c5eb5SMarcel Holtmann 			data = &ctv;
1036767c5eb5SMarcel Holtmann 			len = sizeof(ctv);
1037767c5eb5SMarcel Holtmann 		}
10381da97f83SDavid S. Miller #endif
1039767c5eb5SMarcel Holtmann 
1040767c5eb5SMarcel Holtmann 		put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, len, data);
1041a61bbcf2SPatrick McHardy 	}
10421da177e4SLinus Torvalds }
10431da177e4SLinus Torvalds 
10448528d3f7SMarcel Holtmann static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg,
10458528d3f7SMarcel Holtmann 			    size_t len, int flags)
10461da177e4SLinus Torvalds {
10471da177e4SLinus Torvalds 	int noblock = flags & MSG_DONTWAIT;
10481da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
10491da177e4SLinus Torvalds 	struct sk_buff *skb;
10501da177e4SLinus Torvalds 	int copied, err;
105183871f8cSDenis Kenzior 	unsigned int skblen;
10521da177e4SLinus Torvalds 
10531da177e4SLinus Torvalds 	BT_DBG("sock %p, sk %p", sock, sk);
10541da177e4SLinus Torvalds 
1055d94a6104SMarcel Holtmann 	if (flags & MSG_OOB)
10561da177e4SLinus Torvalds 		return -EOPNOTSUPP;
10571da177e4SLinus Torvalds 
1058ac714949SMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_LOGGING)
1059ac714949SMarcel Holtmann 		return -EOPNOTSUPP;
1060ac714949SMarcel Holtmann 
10611da177e4SLinus Torvalds 	if (sk->sk_state == BT_CLOSED)
10621da177e4SLinus Torvalds 		return 0;
10631da177e4SLinus Torvalds 
106470f23020SAndrei Emeltchenko 	skb = skb_recv_datagram(sk, flags, noblock, &err);
106570f23020SAndrei Emeltchenko 	if (!skb)
10661da177e4SLinus Torvalds 		return err;
10671da177e4SLinus Torvalds 
106883871f8cSDenis Kenzior 	skblen = skb->len;
10691da177e4SLinus Torvalds 	copied = skb->len;
10701da177e4SLinus Torvalds 	if (len < copied) {
10711da177e4SLinus Torvalds 		msg->msg_flags |= MSG_TRUNC;
10721da177e4SLinus Torvalds 		copied = len;
10731da177e4SLinus Torvalds 	}
10741da177e4SLinus Torvalds 
1075badff6d0SArnaldo Carvalho de Melo 	skb_reset_transport_header(skb);
107651f3d02bSDavid S. Miller 	err = skb_copy_datagram_msg(skb, 0, msg, copied);
10771da177e4SLinus Torvalds 
10783a208627SMarcel Holtmann 	switch (hci_pi(sk)->channel) {
10793a208627SMarcel Holtmann 	case HCI_CHANNEL_RAW:
10801da177e4SLinus Torvalds 		hci_sock_cmsg(sk, msg, skb);
10813a208627SMarcel Holtmann 		break;
108223500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
1083cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
1084cd82e61cSMarcel Holtmann 		sock_recv_timestamp(msg, sk, skb);
1085cd82e61cSMarcel Holtmann 		break;
1086801c1e8dSJohan Hedberg 	default:
1087801c1e8dSJohan Hedberg 		if (hci_mgmt_chan_find(hci_pi(sk)->channel))
1088801c1e8dSJohan Hedberg 			sock_recv_timestamp(msg, sk, skb);
1089801c1e8dSJohan Hedberg 		break;
10903a208627SMarcel Holtmann 	}
10911da177e4SLinus Torvalds 
10921da177e4SLinus Torvalds 	skb_free_datagram(sk, skb);
10931da177e4SLinus Torvalds 
1094*4f34228bSLuiz Augusto von Dentz 	if (flags & MSG_TRUNC)
109583871f8cSDenis Kenzior 		copied = skblen;
109683871f8cSDenis Kenzior 
10971da177e4SLinus Torvalds 	return err ? : copied;
10981da177e4SLinus Torvalds }
10991da177e4SLinus Torvalds 
1100fa4335d7SJohan Hedberg static int hci_mgmt_cmd(struct hci_mgmt_chan *chan, struct sock *sk,
1101fa4335d7SJohan Hedberg 			struct msghdr *msg, size_t msglen)
1102fa4335d7SJohan Hedberg {
1103fa4335d7SJohan Hedberg 	void *buf;
1104fa4335d7SJohan Hedberg 	u8 *cp;
1105fa4335d7SJohan Hedberg 	struct mgmt_hdr *hdr;
1106fa4335d7SJohan Hedberg 	u16 opcode, index, len;
1107fa4335d7SJohan Hedberg 	struct hci_dev *hdev = NULL;
1108fa4335d7SJohan Hedberg 	const struct hci_mgmt_handler *handler;
1109fa4335d7SJohan Hedberg 	bool var_len, no_hdev;
1110fa4335d7SJohan Hedberg 	int err;
1111fa4335d7SJohan Hedberg 
1112fa4335d7SJohan Hedberg 	BT_DBG("got %zu bytes", msglen);
1113fa4335d7SJohan Hedberg 
1114fa4335d7SJohan Hedberg 	if (msglen < sizeof(*hdr))
1115fa4335d7SJohan Hedberg 		return -EINVAL;
1116fa4335d7SJohan Hedberg 
1117fa4335d7SJohan Hedberg 	buf = kmalloc(msglen, GFP_KERNEL);
1118fa4335d7SJohan Hedberg 	if (!buf)
1119fa4335d7SJohan Hedberg 		return -ENOMEM;
1120fa4335d7SJohan Hedberg 
1121fa4335d7SJohan Hedberg 	if (memcpy_from_msg(buf, msg, msglen)) {
1122fa4335d7SJohan Hedberg 		err = -EFAULT;
1123fa4335d7SJohan Hedberg 		goto done;
1124fa4335d7SJohan Hedberg 	}
1125fa4335d7SJohan Hedberg 
1126fa4335d7SJohan Hedberg 	hdr = buf;
1127fa4335d7SJohan Hedberg 	opcode = __le16_to_cpu(hdr->opcode);
1128fa4335d7SJohan Hedberg 	index = __le16_to_cpu(hdr->index);
1129fa4335d7SJohan Hedberg 	len = __le16_to_cpu(hdr->len);
1130fa4335d7SJohan Hedberg 
1131fa4335d7SJohan Hedberg 	if (len != msglen - sizeof(*hdr)) {
1132fa4335d7SJohan Hedberg 		err = -EINVAL;
1133fa4335d7SJohan Hedberg 		goto done;
1134fa4335d7SJohan Hedberg 	}
1135fa4335d7SJohan Hedberg 
1136fa4335d7SJohan Hedberg 	if (opcode >= chan->handler_count ||
1137fa4335d7SJohan Hedberg 	    chan->handlers[opcode].func == NULL) {
1138fa4335d7SJohan Hedberg 		BT_DBG("Unknown op %u", opcode);
1139fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1140fa4335d7SJohan Hedberg 				      MGMT_STATUS_UNKNOWN_COMMAND);
1141fa4335d7SJohan Hedberg 		goto done;
1142fa4335d7SJohan Hedberg 	}
1143fa4335d7SJohan Hedberg 
1144fa4335d7SJohan Hedberg 	handler = &chan->handlers[opcode];
1145fa4335d7SJohan Hedberg 
1146fa4335d7SJohan Hedberg 	if (!hci_sock_test_flag(sk, HCI_SOCK_TRUSTED) &&
1147fa4335d7SJohan Hedberg 	    !(handler->flags & HCI_MGMT_UNTRUSTED)) {
1148fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1149fa4335d7SJohan Hedberg 				      MGMT_STATUS_PERMISSION_DENIED);
1150fa4335d7SJohan Hedberg 		goto done;
1151fa4335d7SJohan Hedberg 	}
1152fa4335d7SJohan Hedberg 
1153fa4335d7SJohan Hedberg 	if (index != MGMT_INDEX_NONE) {
1154fa4335d7SJohan Hedberg 		hdev = hci_dev_get(index);
1155fa4335d7SJohan Hedberg 		if (!hdev) {
1156fa4335d7SJohan Hedberg 			err = mgmt_cmd_status(sk, index, opcode,
1157fa4335d7SJohan Hedberg 					      MGMT_STATUS_INVALID_INDEX);
1158fa4335d7SJohan Hedberg 			goto done;
1159fa4335d7SJohan Hedberg 		}
1160fa4335d7SJohan Hedberg 
1161fa4335d7SJohan Hedberg 		if (hci_dev_test_flag(hdev, HCI_SETUP) ||
1162fa4335d7SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_CONFIG) ||
1163fa4335d7SJohan Hedberg 		    hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) {
1164fa4335d7SJohan Hedberg 			err = mgmt_cmd_status(sk, index, opcode,
1165fa4335d7SJohan Hedberg 					      MGMT_STATUS_INVALID_INDEX);
1166fa4335d7SJohan Hedberg 			goto done;
1167fa4335d7SJohan Hedberg 		}
1168fa4335d7SJohan Hedberg 
1169fa4335d7SJohan Hedberg 		if (hci_dev_test_flag(hdev, HCI_UNCONFIGURED) &&
1170fa4335d7SJohan Hedberg 		    !(handler->flags & HCI_MGMT_UNCONFIGURED)) {
1171fa4335d7SJohan Hedberg 			err = mgmt_cmd_status(sk, index, opcode,
1172fa4335d7SJohan Hedberg 					      MGMT_STATUS_INVALID_INDEX);
1173fa4335d7SJohan Hedberg 			goto done;
1174fa4335d7SJohan Hedberg 		}
1175fa4335d7SJohan Hedberg 	}
1176fa4335d7SJohan Hedberg 
1177fa4335d7SJohan Hedberg 	no_hdev = (handler->flags & HCI_MGMT_NO_HDEV);
1178fa4335d7SJohan Hedberg 	if (no_hdev != !hdev) {
1179fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1180fa4335d7SJohan Hedberg 				      MGMT_STATUS_INVALID_INDEX);
1181fa4335d7SJohan Hedberg 		goto done;
1182fa4335d7SJohan Hedberg 	}
1183fa4335d7SJohan Hedberg 
1184fa4335d7SJohan Hedberg 	var_len = (handler->flags & HCI_MGMT_VAR_LEN);
1185fa4335d7SJohan Hedberg 	if ((var_len && len < handler->data_len) ||
1186fa4335d7SJohan Hedberg 	    (!var_len && len != handler->data_len)) {
1187fa4335d7SJohan Hedberg 		err = mgmt_cmd_status(sk, index, opcode,
1188fa4335d7SJohan Hedberg 				      MGMT_STATUS_INVALID_PARAMS);
1189fa4335d7SJohan Hedberg 		goto done;
1190fa4335d7SJohan Hedberg 	}
1191fa4335d7SJohan Hedberg 
1192fa4335d7SJohan Hedberg 	if (hdev && chan->hdev_init)
1193fa4335d7SJohan Hedberg 		chan->hdev_init(sk, hdev);
1194fa4335d7SJohan Hedberg 
1195fa4335d7SJohan Hedberg 	cp = buf + sizeof(*hdr);
1196fa4335d7SJohan Hedberg 
1197fa4335d7SJohan Hedberg 	err = handler->func(sk, hdev, cp, len);
1198fa4335d7SJohan Hedberg 	if (err < 0)
1199fa4335d7SJohan Hedberg 		goto done;
1200fa4335d7SJohan Hedberg 
1201fa4335d7SJohan Hedberg 	err = msglen;
1202fa4335d7SJohan Hedberg 
1203fa4335d7SJohan Hedberg done:
1204fa4335d7SJohan Hedberg 	if (hdev)
1205fa4335d7SJohan Hedberg 		hci_dev_put(hdev);
1206fa4335d7SJohan Hedberg 
1207fa4335d7SJohan Hedberg 	kfree(buf);
1208fa4335d7SJohan Hedberg 	return err;
1209fa4335d7SJohan Hedberg }
1210fa4335d7SJohan Hedberg 
1211ac714949SMarcel Holtmann static int hci_logging_frame(struct sock *sk, struct msghdr *msg, int len)
1212ac714949SMarcel Holtmann {
1213ac714949SMarcel Holtmann 	struct hci_mon_hdr *hdr;
1214ac714949SMarcel Holtmann 	struct sk_buff *skb;
1215ac714949SMarcel Holtmann 	struct hci_dev *hdev;
1216ac714949SMarcel Holtmann 	u16 index;
1217ac714949SMarcel Holtmann 	int err;
1218ac714949SMarcel Holtmann 
1219ac714949SMarcel Holtmann 	/* The logging frame consists at minimum of the standard header,
1220ac714949SMarcel Holtmann 	 * the priority byte, the ident length byte and at least one string
1221ac714949SMarcel Holtmann 	 * terminator NUL byte. Anything shorter are invalid packets.
1222ac714949SMarcel Holtmann 	 */
1223ac714949SMarcel Holtmann 	if (len < sizeof(*hdr) + 3)
1224ac714949SMarcel Holtmann 		return -EINVAL;
1225ac714949SMarcel Holtmann 
1226ac714949SMarcel Holtmann 	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
1227ac714949SMarcel Holtmann 	if (!skb)
1228ac714949SMarcel Holtmann 		return err;
1229ac714949SMarcel Holtmann 
1230ac714949SMarcel Holtmann 	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
1231ac714949SMarcel Holtmann 		err = -EFAULT;
1232ac714949SMarcel Holtmann 		goto drop;
1233ac714949SMarcel Holtmann 	}
1234ac714949SMarcel Holtmann 
1235ac714949SMarcel Holtmann 	hdr = (void *)skb->data;
1236ac714949SMarcel Holtmann 
1237ac714949SMarcel Holtmann 	if (__le16_to_cpu(hdr->len) != len - sizeof(*hdr)) {
1238ac714949SMarcel Holtmann 		err = -EINVAL;
1239ac714949SMarcel Holtmann 		goto drop;
1240ac714949SMarcel Holtmann 	}
1241ac714949SMarcel Holtmann 
1242ac714949SMarcel Holtmann 	if (__le16_to_cpu(hdr->opcode) == 0x0000) {
1243ac714949SMarcel Holtmann 		__u8 priority = skb->data[sizeof(*hdr)];
1244ac714949SMarcel Holtmann 		__u8 ident_len = skb->data[sizeof(*hdr) + 1];
1245ac714949SMarcel Holtmann 
1246ac714949SMarcel Holtmann 		/* Only the priorities 0-7 are valid and with that any other
1247ac714949SMarcel Holtmann 		 * value results in an invalid packet.
1248ac714949SMarcel Holtmann 		 *
1249ac714949SMarcel Holtmann 		 * The priority byte is followed by an ident length byte and
1250ac714949SMarcel Holtmann 		 * the NUL terminated ident string. Check that the ident
1251ac714949SMarcel Holtmann 		 * length is not overflowing the packet and also that the
1252ac714949SMarcel Holtmann 		 * ident string itself is NUL terminated. In case the ident
1253ac714949SMarcel Holtmann 		 * length is zero, the length value actually doubles as NUL
1254ac714949SMarcel Holtmann 		 * terminator identifier.
1255ac714949SMarcel Holtmann 		 *
1256ac714949SMarcel Holtmann 		 * The message follows the ident string (if present) and
1257ac714949SMarcel Holtmann 		 * must be NUL terminated. Otherwise it is not a valid packet.
1258ac714949SMarcel Holtmann 		 */
1259ac714949SMarcel Holtmann 		if (priority > 7 || skb->data[len - 1] != 0x00 ||
1260ac714949SMarcel Holtmann 		    ident_len > len - sizeof(*hdr) - 3 ||
1261ac714949SMarcel Holtmann 		    skb->data[sizeof(*hdr) + ident_len + 1] != 0x00) {
1262ac714949SMarcel Holtmann 			err = -EINVAL;
1263ac714949SMarcel Holtmann 			goto drop;
1264ac714949SMarcel Holtmann 		}
1265ac714949SMarcel Holtmann 	} else {
1266ac714949SMarcel Holtmann 		err = -EINVAL;
1267ac714949SMarcel Holtmann 		goto drop;
1268ac714949SMarcel Holtmann 	}
1269ac714949SMarcel Holtmann 
1270ac714949SMarcel Holtmann 	index = __le16_to_cpu(hdr->index);
1271ac714949SMarcel Holtmann 
1272ac714949SMarcel Holtmann 	if (index != MGMT_INDEX_NONE) {
1273ac714949SMarcel Holtmann 		hdev = hci_dev_get(index);
1274ac714949SMarcel Holtmann 		if (!hdev) {
1275ac714949SMarcel Holtmann 			err = -ENODEV;
1276ac714949SMarcel Holtmann 			goto drop;
1277ac714949SMarcel Holtmann 		}
1278ac714949SMarcel Holtmann 	} else {
1279ac714949SMarcel Holtmann 		hdev = NULL;
1280ac714949SMarcel Holtmann 	}
1281ac714949SMarcel Holtmann 
1282ac714949SMarcel Holtmann 	hdr->opcode = cpu_to_le16(HCI_MON_USER_LOGGING);
1283ac714949SMarcel Holtmann 
1284ac714949SMarcel Holtmann 	hci_send_to_channel(HCI_CHANNEL_MONITOR, skb, HCI_SOCK_TRUSTED, NULL);
1285ac714949SMarcel Holtmann 	err = len;
1286ac714949SMarcel Holtmann 
1287ac714949SMarcel Holtmann 	if (hdev)
1288ac714949SMarcel Holtmann 		hci_dev_put(hdev);
1289ac714949SMarcel Holtmann 
1290ac714949SMarcel Holtmann drop:
1291ac714949SMarcel Holtmann 	kfree_skb(skb);
1292ac714949SMarcel Holtmann 	return err;
1293ac714949SMarcel Holtmann }
1294ac714949SMarcel Holtmann 
12951b784140SYing Xue static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg,
12961b784140SYing Xue 			    size_t len)
12971da177e4SLinus Torvalds {
12981da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1299801c1e8dSJohan Hedberg 	struct hci_mgmt_chan *chan;
13001da177e4SLinus Torvalds 	struct hci_dev *hdev;
13011da177e4SLinus Torvalds 	struct sk_buff *skb;
13021da177e4SLinus Torvalds 	int err;
13031da177e4SLinus Torvalds 
13041da177e4SLinus Torvalds 	BT_DBG("sock %p sk %p", sock, sk);
13051da177e4SLinus Torvalds 
13061da177e4SLinus Torvalds 	if (msg->msg_flags & MSG_OOB)
13071da177e4SLinus Torvalds 		return -EOPNOTSUPP;
13081da177e4SLinus Torvalds 
13091da177e4SLinus Torvalds 	if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
13101da177e4SLinus Torvalds 		return -EINVAL;
13111da177e4SLinus Torvalds 
13121da177e4SLinus Torvalds 	if (len < 4 || len > HCI_MAX_FRAME_SIZE)
13131da177e4SLinus Torvalds 		return -EINVAL;
13141da177e4SLinus Torvalds 
13151da177e4SLinus Torvalds 	lock_sock(sk);
13161da177e4SLinus Torvalds 
13170381101fSJohan Hedberg 	switch (hci_pi(sk)->channel) {
13180381101fSJohan Hedberg 	case HCI_CHANNEL_RAW:
131923500189SMarcel Holtmann 	case HCI_CHANNEL_USER:
13200381101fSJohan Hedberg 		break;
1321cd82e61cSMarcel Holtmann 	case HCI_CHANNEL_MONITOR:
1322cd82e61cSMarcel Holtmann 		err = -EOPNOTSUPP;
1323cd82e61cSMarcel Holtmann 		goto done;
1324ac714949SMarcel Holtmann 	case HCI_CHANNEL_LOGGING:
1325ac714949SMarcel Holtmann 		err = hci_logging_frame(sk, msg, len);
1326ac714949SMarcel Holtmann 		goto done;
13270381101fSJohan Hedberg 	default:
1328801c1e8dSJohan Hedberg 		mutex_lock(&mgmt_chan_list_lock);
1329801c1e8dSJohan Hedberg 		chan = __hci_mgmt_chan_find(hci_pi(sk)->channel);
1330801c1e8dSJohan Hedberg 		if (chan)
1331fa4335d7SJohan Hedberg 			err = hci_mgmt_cmd(chan, sk, msg, len);
1332801c1e8dSJohan Hedberg 		else
13330381101fSJohan Hedberg 			err = -EINVAL;
1334801c1e8dSJohan Hedberg 
1335801c1e8dSJohan Hedberg 		mutex_unlock(&mgmt_chan_list_lock);
13360381101fSJohan Hedberg 		goto done;
13370381101fSJohan Hedberg 	}
13380381101fSJohan Hedberg 
133970f23020SAndrei Emeltchenko 	hdev = hci_pi(sk)->hdev;
134070f23020SAndrei Emeltchenko 	if (!hdev) {
13411da177e4SLinus Torvalds 		err = -EBADFD;
13421da177e4SLinus Torvalds 		goto done;
13431da177e4SLinus Torvalds 	}
13441da177e4SLinus Torvalds 
13457e21addcSMarcel Holtmann 	if (!test_bit(HCI_UP, &hdev->flags)) {
13467e21addcSMarcel Holtmann 		err = -ENETDOWN;
13477e21addcSMarcel Holtmann 		goto done;
13487e21addcSMarcel Holtmann 	}
13497e21addcSMarcel Holtmann 
135070f23020SAndrei Emeltchenko 	skb = bt_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err);
135170f23020SAndrei Emeltchenko 	if (!skb)
13521da177e4SLinus Torvalds 		goto done;
13531da177e4SLinus Torvalds 
13546ce8e9ceSAl Viro 	if (memcpy_from_msg(skb_put(skb, len), msg, len)) {
13551da177e4SLinus Torvalds 		err = -EFAULT;
13561da177e4SLinus Torvalds 		goto drop;
13571da177e4SLinus Torvalds 	}
13581da177e4SLinus Torvalds 
13598528d3f7SMarcel Holtmann 	hci_skb_pkt_type(skb) = skb->data[0];
13601da177e4SLinus Torvalds 	skb_pull(skb, 1);
13611da177e4SLinus Torvalds 
13621bc5ad16SMarcel Holtmann 	if (hci_pi(sk)->channel == HCI_CHANNEL_USER) {
13631bc5ad16SMarcel Holtmann 		/* No permission check is needed for user channel
13641bc5ad16SMarcel Holtmann 		 * since that gets enforced when binding the socket.
13651bc5ad16SMarcel Holtmann 		 *
13661bc5ad16SMarcel Holtmann 		 * However check that the packet type is valid.
13671bc5ad16SMarcel Holtmann 		 */
1368d79f34e3SMarcel Holtmann 		if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT &&
1369d79f34e3SMarcel Holtmann 		    hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
1370d79f34e3SMarcel Holtmann 		    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) {
13711bc5ad16SMarcel Holtmann 			err = -EINVAL;
13721bc5ad16SMarcel Holtmann 			goto drop;
13731bc5ad16SMarcel Holtmann 		}
13741bc5ad16SMarcel Holtmann 
13751bc5ad16SMarcel Holtmann 		skb_queue_tail(&hdev->raw_q, skb);
13761bc5ad16SMarcel Holtmann 		queue_work(hdev->workqueue, &hdev->tx_work);
1377d79f34e3SMarcel Holtmann 	} else if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) {
137883985319SHarvey Harrison 		u16 opcode = get_unaligned_le16(skb->data);
13791da177e4SLinus Torvalds 		u16 ogf = hci_opcode_ogf(opcode);
13801da177e4SLinus Torvalds 		u16 ocf = hci_opcode_ocf(opcode);
13811da177e4SLinus Torvalds 
13821da177e4SLinus Torvalds 		if (((ogf > HCI_SFLT_MAX_OGF) ||
13833bb3c755SGustavo Padovan 		     !hci_test_bit(ocf & HCI_FLT_OCF_BITS,
13843bb3c755SGustavo Padovan 				   &hci_sec_filter.ocf_mask[ogf])) &&
13851da177e4SLinus Torvalds 		    !capable(CAP_NET_RAW)) {
13861da177e4SLinus Torvalds 			err = -EPERM;
13871da177e4SLinus Torvalds 			goto drop;
13881da177e4SLinus Torvalds 		}
13891da177e4SLinus Torvalds 
13901982162bSMarcel Holtmann 		/* Since the opcode has already been extracted here, store
13911982162bSMarcel Holtmann 		 * a copy of the value for later use by the drivers.
13921982162bSMarcel Holtmann 		 */
13931982162bSMarcel Holtmann 		hci_skb_opcode(skb) = opcode;
13941982162bSMarcel Holtmann 
1395fee746b0SMarcel Holtmann 		if (ogf == 0x3f) {
13961da177e4SLinus Torvalds 			skb_queue_tail(&hdev->raw_q, skb);
13973eff45eaSGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->tx_work);
13981da177e4SLinus Torvalds 		} else {
139949c922bbSStephen Hemminger 			/* Stand-alone HCI commands must be flagged as
140011714b3dSJohan Hedberg 			 * single-command requests.
140111714b3dSJohan Hedberg 			 */
140244d27137SJohan Hedberg 			bt_cb(skb)->hci.req_flags |= HCI_REQ_START;
140311714b3dSJohan Hedberg 
14041da177e4SLinus Torvalds 			skb_queue_tail(&hdev->cmd_q, skb);
1405c347b765SGustavo F. Padovan 			queue_work(hdev->workqueue, &hdev->cmd_work);
14061da177e4SLinus Torvalds 		}
14071da177e4SLinus Torvalds 	} else {
14081da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
14091da177e4SLinus Torvalds 			err = -EPERM;
14101da177e4SLinus Torvalds 			goto drop;
14111da177e4SLinus Torvalds 		}
14121da177e4SLinus Torvalds 
1413d79f34e3SMarcel Holtmann 		if (hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT &&
1414d79f34e3SMarcel Holtmann 		    hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) {
1415bb77543eSMarcel Holtmann 			err = -EINVAL;
1416bb77543eSMarcel Holtmann 			goto drop;
1417bb77543eSMarcel Holtmann 		}
1418bb77543eSMarcel Holtmann 
14191da177e4SLinus Torvalds 		skb_queue_tail(&hdev->raw_q, skb);
14203eff45eaSGustavo F. Padovan 		queue_work(hdev->workqueue, &hdev->tx_work);
14211da177e4SLinus Torvalds 	}
14221da177e4SLinus Torvalds 
14231da177e4SLinus Torvalds 	err = len;
14241da177e4SLinus Torvalds 
14251da177e4SLinus Torvalds done:
14261da177e4SLinus Torvalds 	release_sock(sk);
14271da177e4SLinus Torvalds 	return err;
14281da177e4SLinus Torvalds 
14291da177e4SLinus Torvalds drop:
14301da177e4SLinus Torvalds 	kfree_skb(skb);
14311da177e4SLinus Torvalds 	goto done;
14321da177e4SLinus Torvalds }
14331da177e4SLinus Torvalds 
14348fc9ced3SGustavo Padovan static int hci_sock_setsockopt(struct socket *sock, int level, int optname,
14358fc9ced3SGustavo Padovan 			       char __user *optval, unsigned int len)
14361da177e4SLinus Torvalds {
14371da177e4SLinus Torvalds 	struct hci_ufilter uf = { .opcode = 0 };
14381da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
14391da177e4SLinus Torvalds 	int err = 0, opt = 0;
14401da177e4SLinus Torvalds 
14411da177e4SLinus Torvalds 	BT_DBG("sk %p, opt %d", sk, optname);
14421da177e4SLinus Torvalds 
14431da177e4SLinus Torvalds 	lock_sock(sk);
14441da177e4SLinus Torvalds 
14452f39cdb7SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1446c2371e80SMarcel Holtmann 		err = -EBADFD;
14472f39cdb7SMarcel Holtmann 		goto done;
14482f39cdb7SMarcel Holtmann 	}
14492f39cdb7SMarcel Holtmann 
14501da177e4SLinus Torvalds 	switch (optname) {
14511da177e4SLinus Torvalds 	case HCI_DATA_DIR:
14521da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
14531da177e4SLinus Torvalds 			err = -EFAULT;
14541da177e4SLinus Torvalds 			break;
14551da177e4SLinus Torvalds 		}
14561da177e4SLinus Torvalds 
14571da177e4SLinus Torvalds 		if (opt)
14581da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
14591da177e4SLinus Torvalds 		else
14601da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
14611da177e4SLinus Torvalds 		break;
14621da177e4SLinus Torvalds 
14631da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
14641da177e4SLinus Torvalds 		if (get_user(opt, (int __user *)optval)) {
14651da177e4SLinus Torvalds 			err = -EFAULT;
14661da177e4SLinus Torvalds 			break;
14671da177e4SLinus Torvalds 		}
14681da177e4SLinus Torvalds 
14691da177e4SLinus Torvalds 		if (opt)
14701da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
14711da177e4SLinus Torvalds 		else
14721da177e4SLinus Torvalds 			hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
14731da177e4SLinus Torvalds 		break;
14741da177e4SLinus Torvalds 
14751da177e4SLinus Torvalds 	case HCI_FILTER:
14760878b666SMarcel Holtmann 		{
14770878b666SMarcel Holtmann 			struct hci_filter *f = &hci_pi(sk)->filter;
14780878b666SMarcel Holtmann 
14790878b666SMarcel Holtmann 			uf.type_mask = f->type_mask;
14800878b666SMarcel Holtmann 			uf.opcode    = f->opcode;
14810878b666SMarcel Holtmann 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
14820878b666SMarcel Holtmann 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
14830878b666SMarcel Holtmann 		}
14840878b666SMarcel Holtmann 
14851da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
14861da177e4SLinus Torvalds 		if (copy_from_user(&uf, optval, len)) {
14871da177e4SLinus Torvalds 			err = -EFAULT;
14881da177e4SLinus Torvalds 			break;
14891da177e4SLinus Torvalds 		}
14901da177e4SLinus Torvalds 
14911da177e4SLinus Torvalds 		if (!capable(CAP_NET_RAW)) {
14921da177e4SLinus Torvalds 			uf.type_mask &= hci_sec_filter.type_mask;
14931da177e4SLinus Torvalds 			uf.event_mask[0] &= *((u32 *) hci_sec_filter.event_mask + 0);
14941da177e4SLinus Torvalds 			uf.event_mask[1] &= *((u32 *) hci_sec_filter.event_mask + 1);
14951da177e4SLinus Torvalds 		}
14961da177e4SLinus Torvalds 
14971da177e4SLinus Torvalds 		{
14981da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
14991da177e4SLinus Torvalds 
15001da177e4SLinus Torvalds 			f->type_mask = uf.type_mask;
15011da177e4SLinus Torvalds 			f->opcode    = uf.opcode;
15021da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 0) = uf.event_mask[0];
15031da177e4SLinus Torvalds 			*((u32 *) f->event_mask + 1) = uf.event_mask[1];
15041da177e4SLinus Torvalds 		}
15051da177e4SLinus Torvalds 		break;
15061da177e4SLinus Torvalds 
15071da177e4SLinus Torvalds 	default:
15081da177e4SLinus Torvalds 		err = -ENOPROTOOPT;
15091da177e4SLinus Torvalds 		break;
15101da177e4SLinus Torvalds 	}
15111da177e4SLinus Torvalds 
15122f39cdb7SMarcel Holtmann done:
15131da177e4SLinus Torvalds 	release_sock(sk);
15141da177e4SLinus Torvalds 	return err;
15151da177e4SLinus Torvalds }
15161da177e4SLinus Torvalds 
15178fc9ced3SGustavo Padovan static int hci_sock_getsockopt(struct socket *sock, int level, int optname,
15188fc9ced3SGustavo Padovan 			       char __user *optval, int __user *optlen)
15191da177e4SLinus Torvalds {
15201da177e4SLinus Torvalds 	struct hci_ufilter uf;
15211da177e4SLinus Torvalds 	struct sock *sk = sock->sk;
1522cedc5469SMarcel Holtmann 	int len, opt, err = 0;
1523cedc5469SMarcel Holtmann 
1524cedc5469SMarcel Holtmann 	BT_DBG("sk %p, opt %d", sk, optname);
15251da177e4SLinus Torvalds 
15261da177e4SLinus Torvalds 	if (get_user(len, optlen))
15271da177e4SLinus Torvalds 		return -EFAULT;
15281da177e4SLinus Torvalds 
1529cedc5469SMarcel Holtmann 	lock_sock(sk);
1530cedc5469SMarcel Holtmann 
1531cedc5469SMarcel Holtmann 	if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) {
1532c2371e80SMarcel Holtmann 		err = -EBADFD;
1533cedc5469SMarcel Holtmann 		goto done;
1534cedc5469SMarcel Holtmann 	}
1535cedc5469SMarcel Holtmann 
15361da177e4SLinus Torvalds 	switch (optname) {
15371da177e4SLinus Torvalds 	case HCI_DATA_DIR:
15381da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_DIR)
15391da177e4SLinus Torvalds 			opt = 1;
15401da177e4SLinus Torvalds 		else
15411da177e4SLinus Torvalds 			opt = 0;
15421da177e4SLinus Torvalds 
15431da177e4SLinus Torvalds 		if (put_user(opt, optval))
1544cedc5469SMarcel Holtmann 			err = -EFAULT;
15451da177e4SLinus Torvalds 		break;
15461da177e4SLinus Torvalds 
15471da177e4SLinus Torvalds 	case HCI_TIME_STAMP:
15481da177e4SLinus Torvalds 		if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
15491da177e4SLinus Torvalds 			opt = 1;
15501da177e4SLinus Torvalds 		else
15511da177e4SLinus Torvalds 			opt = 0;
15521da177e4SLinus Torvalds 
15531da177e4SLinus Torvalds 		if (put_user(opt, optval))
1554cedc5469SMarcel Holtmann 			err = -EFAULT;
15551da177e4SLinus Torvalds 		break;
15561da177e4SLinus Torvalds 
15571da177e4SLinus Torvalds 	case HCI_FILTER:
15581da177e4SLinus Torvalds 		{
15591da177e4SLinus Torvalds 			struct hci_filter *f = &hci_pi(sk)->filter;
15601da177e4SLinus Torvalds 
1561e15ca9a0SMathias Krause 			memset(&uf, 0, sizeof(uf));
15621da177e4SLinus Torvalds 			uf.type_mask = f->type_mask;
15631da177e4SLinus Torvalds 			uf.opcode    = f->opcode;
15641da177e4SLinus Torvalds 			uf.event_mask[0] = *((u32 *) f->event_mask + 0);
15651da177e4SLinus Torvalds 			uf.event_mask[1] = *((u32 *) f->event_mask + 1);
15661da177e4SLinus Torvalds 		}
15671da177e4SLinus Torvalds 
15681da177e4SLinus Torvalds 		len = min_t(unsigned int, len, sizeof(uf));
15691da177e4SLinus Torvalds 		if (copy_to_user(optval, &uf, len))
1570cedc5469SMarcel Holtmann 			err = -EFAULT;
15711da177e4SLinus Torvalds 		break;
15721da177e4SLinus Torvalds 
15731da177e4SLinus Torvalds 	default:
1574cedc5469SMarcel Holtmann 		err = -ENOPROTOOPT;
15751da177e4SLinus Torvalds 		break;
15761da177e4SLinus Torvalds 	}
15771da177e4SLinus Torvalds 
1578cedc5469SMarcel Holtmann done:
1579cedc5469SMarcel Holtmann 	release_sock(sk);
1580cedc5469SMarcel Holtmann 	return err;
15811da177e4SLinus Torvalds }
15821da177e4SLinus Torvalds 
158390ddc4f0SEric Dumazet static const struct proto_ops hci_sock_ops = {
15841da177e4SLinus Torvalds 	.family		= PF_BLUETOOTH,
15851da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
15861da177e4SLinus Torvalds 	.release	= hci_sock_release,
15871da177e4SLinus Torvalds 	.bind		= hci_sock_bind,
15881da177e4SLinus Torvalds 	.getname	= hci_sock_getname,
15891da177e4SLinus Torvalds 	.sendmsg	= hci_sock_sendmsg,
15901da177e4SLinus Torvalds 	.recvmsg	= hci_sock_recvmsg,
15911da177e4SLinus Torvalds 	.ioctl		= hci_sock_ioctl,
15921da177e4SLinus Torvalds 	.poll		= datagram_poll,
15931da177e4SLinus Torvalds 	.listen		= sock_no_listen,
15941da177e4SLinus Torvalds 	.shutdown	= sock_no_shutdown,
15951da177e4SLinus Torvalds 	.setsockopt	= hci_sock_setsockopt,
15961da177e4SLinus Torvalds 	.getsockopt	= hci_sock_getsockopt,
15971da177e4SLinus Torvalds 	.connect	= sock_no_connect,
15981da177e4SLinus Torvalds 	.socketpair	= sock_no_socketpair,
15991da177e4SLinus Torvalds 	.accept		= sock_no_accept,
16001da177e4SLinus Torvalds 	.mmap		= sock_no_mmap
16011da177e4SLinus Torvalds };
16021da177e4SLinus Torvalds 
16031da177e4SLinus Torvalds static struct proto hci_sk_proto = {
16041da177e4SLinus Torvalds 	.name		= "HCI",
16051da177e4SLinus Torvalds 	.owner		= THIS_MODULE,
16061da177e4SLinus Torvalds 	.obj_size	= sizeof(struct hci_pinfo)
16071da177e4SLinus Torvalds };
16081da177e4SLinus Torvalds 
16093f378b68SEric Paris static int hci_sock_create(struct net *net, struct socket *sock, int protocol,
16103f378b68SEric Paris 			   int kern)
16111da177e4SLinus Torvalds {
16121da177e4SLinus Torvalds 	struct sock *sk;
16131da177e4SLinus Torvalds 
16141da177e4SLinus Torvalds 	BT_DBG("sock %p", sock);
16151da177e4SLinus Torvalds 
16161da177e4SLinus Torvalds 	if (sock->type != SOCK_RAW)
16171da177e4SLinus Torvalds 		return -ESOCKTNOSUPPORT;
16181da177e4SLinus Torvalds 
16191da177e4SLinus Torvalds 	sock->ops = &hci_sock_ops;
16201da177e4SLinus Torvalds 
162111aa9c28SEric W. Biederman 	sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hci_sk_proto, kern);
16221da177e4SLinus Torvalds 	if (!sk)
16231da177e4SLinus Torvalds 		return -ENOMEM;
16241da177e4SLinus Torvalds 
16251da177e4SLinus Torvalds 	sock_init_data(sock, sk);
16261da177e4SLinus Torvalds 
16271da177e4SLinus Torvalds 	sock_reset_flag(sk, SOCK_ZAPPED);
16281da177e4SLinus Torvalds 
16291da177e4SLinus Torvalds 	sk->sk_protocol = protocol;
16301da177e4SLinus Torvalds 
16311da177e4SLinus Torvalds 	sock->state = SS_UNCONNECTED;
16321da177e4SLinus Torvalds 	sk->sk_state = BT_OPEN;
16331da177e4SLinus Torvalds 
16341da177e4SLinus Torvalds 	bt_sock_link(&hci_sk_list, sk);
16351da177e4SLinus Torvalds 	return 0;
16361da177e4SLinus Torvalds }
16371da177e4SLinus Torvalds 
1638ec1b4cf7SStephen Hemminger static const struct net_proto_family hci_sock_family_ops = {
16391da177e4SLinus Torvalds 	.family	= PF_BLUETOOTH,
16401da177e4SLinus Torvalds 	.owner	= THIS_MODULE,
16411da177e4SLinus Torvalds 	.create	= hci_sock_create,
16421da177e4SLinus Torvalds };
16431da177e4SLinus Torvalds 
16441da177e4SLinus Torvalds int __init hci_sock_init(void)
16451da177e4SLinus Torvalds {
16461da177e4SLinus Torvalds 	int err;
16471da177e4SLinus Torvalds 
1648b0a8e282SMarcel Holtmann 	BUILD_BUG_ON(sizeof(struct sockaddr_hci) > sizeof(struct sockaddr));
1649b0a8e282SMarcel Holtmann 
16501da177e4SLinus Torvalds 	err = proto_register(&hci_sk_proto, 0);
16511da177e4SLinus Torvalds 	if (err < 0)
16521da177e4SLinus Torvalds 		return err;
16531da177e4SLinus Torvalds 
16541da177e4SLinus Torvalds 	err = bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
1655f7c86637SMasatake YAMATO 	if (err < 0) {
1656f7c86637SMasatake YAMATO 		BT_ERR("HCI socket registration failed");
16571da177e4SLinus Torvalds 		goto error;
1658f7c86637SMasatake YAMATO 	}
1659f7c86637SMasatake YAMATO 
1660b0316615SAl Viro 	err = bt_procfs_init(&init_net, "hci", &hci_sk_list, NULL);
1661f7c86637SMasatake YAMATO 	if (err < 0) {
1662f7c86637SMasatake YAMATO 		BT_ERR("Failed to create HCI proc file");
1663f7c86637SMasatake YAMATO 		bt_sock_unregister(BTPROTO_HCI);
1664f7c86637SMasatake YAMATO 		goto error;
1665f7c86637SMasatake YAMATO 	}
16661da177e4SLinus Torvalds 
16671da177e4SLinus Torvalds 	BT_INFO("HCI socket layer initialized");
16681da177e4SLinus Torvalds 
16691da177e4SLinus Torvalds 	return 0;
16701da177e4SLinus Torvalds 
16711da177e4SLinus Torvalds error:
16721da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
16731da177e4SLinus Torvalds 	return err;
16741da177e4SLinus Torvalds }
16751da177e4SLinus Torvalds 
1676b7440a14SAnand Gadiyar void hci_sock_cleanup(void)
16771da177e4SLinus Torvalds {
1678f7c86637SMasatake YAMATO 	bt_procfs_cleanup(&init_net, "hci");
16795e9d7f86SDavid Herrmann 	bt_sock_unregister(BTPROTO_HCI);
16801da177e4SLinus Torvalds 	proto_unregister(&hci_sk_proto);
16811da177e4SLinus Torvalds }
1682