.. | .. |
---|
23 | 23 | */ |
---|
24 | 24 | |
---|
25 | 25 | /* Bluetooth HCI sockets. */ |
---|
26 | | - |
---|
| 26 | +#include <linux/compat.h> |
---|
27 | 27 | #include <linux/export.h> |
---|
28 | 28 | #include <linux/utsname.h> |
---|
29 | 29 | #include <linux/sched.h> |
---|
.. | .. |
---|
52 | 52 | struct bt_sock bt; |
---|
53 | 53 | struct hci_dev *hdev; |
---|
54 | 54 | struct hci_filter filter; |
---|
55 | | - __u32 cmsg_mask; |
---|
| 55 | + __u8 cmsg_mask; |
---|
56 | 56 | unsigned short channel; |
---|
57 | 57 | unsigned long flags; |
---|
58 | 58 | __u32 cookie; |
---|
.. | .. |
---|
222 | 222 | if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT && |
---|
223 | 223 | hci_skb_pkt_type(skb) != HCI_EVENT_PKT && |
---|
224 | 224 | hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
---|
225 | | - hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) |
---|
| 225 | + hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && |
---|
| 226 | + hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) |
---|
226 | 227 | continue; |
---|
227 | 228 | if (is_filtered_packet(sk, skb)) |
---|
228 | 229 | continue; |
---|
.. | .. |
---|
231 | 232 | continue; |
---|
232 | 233 | if (hci_skb_pkt_type(skb) != HCI_EVENT_PKT && |
---|
233 | 234 | hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
---|
234 | | - hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) |
---|
| 235 | + hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && |
---|
| 236 | + hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) |
---|
235 | 237 | continue; |
---|
236 | 238 | } else { |
---|
237 | 239 | /* Don't send frame to other channel types */ |
---|
.. | .. |
---|
334 | 336 | opcode = cpu_to_le16(HCI_MON_SCO_RX_PKT); |
---|
335 | 337 | else |
---|
336 | 338 | opcode = cpu_to_le16(HCI_MON_SCO_TX_PKT); |
---|
| 339 | + break; |
---|
| 340 | + case HCI_ISODATA_PKT: |
---|
| 341 | + if (bt_cb(skb)->incoming) |
---|
| 342 | + opcode = cpu_to_le16(HCI_MON_ISO_RX_PKT); |
---|
| 343 | + else |
---|
| 344 | + opcode = cpu_to_le16(HCI_MON_ISO_TX_PKT); |
---|
337 | 345 | break; |
---|
338 | 346 | case HCI_DIAG_PKT: |
---|
339 | 347 | opcode = cpu_to_le16(HCI_MON_VENDOR_DIAG); |
---|
.. | .. |
---|
446 | 454 | case HCI_DEV_SETUP: |
---|
447 | 455 | if (hdev->manufacturer == 0xffff) |
---|
448 | 456 | return NULL; |
---|
449 | | - |
---|
450 | | - /* fall through */ |
---|
| 457 | + fallthrough; |
---|
451 | 458 | |
---|
452 | 459 | case HCI_DEV_UP: |
---|
453 | 460 | skb = bt_skb_alloc(HCI_MON_INDEX_INFO_SIZE, GFP_ATOMIC); |
---|
.. | .. |
---|
881 | 888 | } |
---|
882 | 889 | |
---|
883 | 890 | sock_orphan(sk); |
---|
884 | | - |
---|
885 | | - skb_queue_purge(&sk->sk_receive_queue); |
---|
886 | | - skb_queue_purge(&sk->sk_write_queue); |
---|
887 | | - |
---|
888 | 891 | release_sock(sk); |
---|
889 | 892 | sock_put(sk); |
---|
890 | 893 | return 0; |
---|
.. | .. |
---|
977 | 980 | |
---|
978 | 981 | BT_DBG("cmd %x arg %lx", cmd, arg); |
---|
979 | 982 | |
---|
| 983 | + /* Make sure the cmd is valid before doing anything */ |
---|
| 984 | + switch (cmd) { |
---|
| 985 | + case HCIGETDEVLIST: |
---|
| 986 | + case HCIGETDEVINFO: |
---|
| 987 | + case HCIGETCONNLIST: |
---|
| 988 | + case HCIDEVUP: |
---|
| 989 | + case HCIDEVDOWN: |
---|
| 990 | + case HCIDEVRESET: |
---|
| 991 | + case HCIDEVRESTAT: |
---|
| 992 | + case HCISETSCAN: |
---|
| 993 | + case HCISETAUTH: |
---|
| 994 | + case HCISETENCRYPT: |
---|
| 995 | + case HCISETPTYPE: |
---|
| 996 | + case HCISETLINKPOL: |
---|
| 997 | + case HCISETLINKMODE: |
---|
| 998 | + case HCISETACLMTU: |
---|
| 999 | + case HCISETSCOMTU: |
---|
| 1000 | + case HCIINQUIRY: |
---|
| 1001 | + case HCISETRAW: |
---|
| 1002 | + case HCIGETCONNINFO: |
---|
| 1003 | + case HCIGETAUTHINFO: |
---|
| 1004 | + case HCIBLOCKADDR: |
---|
| 1005 | + case HCIUNBLOCKADDR: |
---|
| 1006 | + break; |
---|
| 1007 | + default: |
---|
| 1008 | + return -ENOIOCTLCMD; |
---|
| 1009 | + } |
---|
| 1010 | + |
---|
980 | 1011 | lock_sock(sk); |
---|
981 | 1012 | |
---|
982 | 1013 | if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) { |
---|
.. | .. |
---|
993 | 1024 | if (hci_sock_gen_cookie(sk)) { |
---|
994 | 1025 | struct sk_buff *skb; |
---|
995 | 1026 | |
---|
996 | | - if (capable(CAP_NET_ADMIN)) |
---|
| 1027 | + /* Perform careful checks before setting the HCI_SOCK_TRUSTED |
---|
| 1028 | + * flag. Make sure that not only the current task but also |
---|
| 1029 | + * the socket opener has the required capability, since |
---|
| 1030 | + * privileged programs can be tricked into making ioctl calls |
---|
| 1031 | + * on HCI sockets, and the socket should not be marked as |
---|
| 1032 | + * trusted simply because the ioctl caller is privileged. |
---|
| 1033 | + */ |
---|
| 1034 | + if (sk_capable(sk, CAP_NET_ADMIN)) |
---|
997 | 1035 | hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); |
---|
998 | 1036 | |
---|
999 | 1037 | /* Send event to monitor */ |
---|
.. | .. |
---|
1061 | 1099 | release_sock(sk); |
---|
1062 | 1100 | return err; |
---|
1063 | 1101 | } |
---|
| 1102 | + |
---|
| 1103 | +#ifdef CONFIG_COMPAT |
---|
| 1104 | +static int hci_sock_compat_ioctl(struct socket *sock, unsigned int cmd, |
---|
| 1105 | + unsigned long arg) |
---|
| 1106 | +{ |
---|
| 1107 | + switch (cmd) { |
---|
| 1108 | + case HCIDEVUP: |
---|
| 1109 | + case HCIDEVDOWN: |
---|
| 1110 | + case HCIDEVRESET: |
---|
| 1111 | + case HCIDEVRESTAT: |
---|
| 1112 | + return hci_sock_ioctl(sock, cmd, arg); |
---|
| 1113 | + } |
---|
| 1114 | + |
---|
| 1115 | + return hci_sock_ioctl(sock, cmd, (unsigned long)compat_ptr(arg)); |
---|
| 1116 | +} |
---|
| 1117 | +#endif |
---|
1064 | 1118 | |
---|
1065 | 1119 | static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, |
---|
1066 | 1120 | int addr_len) |
---|
.. | .. |
---|
1392 | 1446 | static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, |
---|
1393 | 1447 | struct sk_buff *skb) |
---|
1394 | 1448 | { |
---|
1395 | | - __u32 mask = hci_pi(sk)->cmsg_mask; |
---|
| 1449 | + __u8 mask = hci_pi(sk)->cmsg_mask; |
---|
1396 | 1450 | |
---|
1397 | 1451 | if (mask & HCI_CMSG_DIR) { |
---|
1398 | 1452 | int incoming = bt_cb(skb)->incoming; |
---|
.. | .. |
---|
1402 | 1456 | |
---|
1403 | 1457 | if (mask & HCI_CMSG_TSTAMP) { |
---|
1404 | 1458 | #ifdef CONFIG_COMPAT |
---|
1405 | | - struct compat_timeval ctv; |
---|
| 1459 | + struct old_timeval32 ctv; |
---|
1406 | 1460 | #endif |
---|
1407 | | - struct timeval tv; |
---|
| 1461 | + struct __kernel_old_timeval tv; |
---|
1408 | 1462 | void *data; |
---|
1409 | 1463 | int len; |
---|
1410 | 1464 | |
---|
.. | .. |
---|
1572 | 1626 | } |
---|
1573 | 1627 | } |
---|
1574 | 1628 | |
---|
1575 | | - no_hdev = (handler->flags & HCI_MGMT_NO_HDEV); |
---|
1576 | | - if (no_hdev != !hdev) { |
---|
1577 | | - err = mgmt_cmd_status(sk, index, opcode, |
---|
1578 | | - MGMT_STATUS_INVALID_INDEX); |
---|
1579 | | - goto done; |
---|
| 1629 | + if (!(handler->flags & HCI_MGMT_HDEV_OPTIONAL)) { |
---|
| 1630 | + no_hdev = (handler->flags & HCI_MGMT_NO_HDEV); |
---|
| 1631 | + if (no_hdev != !hdev) { |
---|
| 1632 | + err = mgmt_cmd_status(sk, index, opcode, |
---|
| 1633 | + MGMT_STATUS_INVALID_INDEX); |
---|
| 1634 | + goto done; |
---|
| 1635 | + } |
---|
1580 | 1636 | } |
---|
1581 | 1637 | |
---|
1582 | 1638 | var_len = (handler->flags & HCI_MGMT_VAR_LEN); |
---|
.. | .. |
---|
1766 | 1822 | */ |
---|
1767 | 1823 | if (hci_skb_pkt_type(skb) != HCI_COMMAND_PKT && |
---|
1768 | 1824 | hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
---|
1769 | | - hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) { |
---|
| 1825 | + hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && |
---|
| 1826 | + hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { |
---|
1770 | 1827 | err = -EINVAL; |
---|
1771 | 1828 | goto drop; |
---|
1772 | 1829 | } |
---|
.. | .. |
---|
1810 | 1867 | } |
---|
1811 | 1868 | |
---|
1812 | 1869 | if (hci_skb_pkt_type(skb) != HCI_ACLDATA_PKT && |
---|
1813 | | - hci_skb_pkt_type(skb) != HCI_SCODATA_PKT) { |
---|
| 1870 | + hci_skb_pkt_type(skb) != HCI_SCODATA_PKT && |
---|
| 1871 | + hci_skb_pkt_type(skb) != HCI_ISODATA_PKT) { |
---|
1814 | 1872 | err = -EINVAL; |
---|
1815 | 1873 | goto drop; |
---|
1816 | 1874 | } |
---|
.. | .. |
---|
1831 | 1889 | } |
---|
1832 | 1890 | |
---|
1833 | 1891 | static int hci_sock_setsockopt(struct socket *sock, int level, int optname, |
---|
1834 | | - char __user *optval, unsigned int len) |
---|
| 1892 | + sockptr_t optval, unsigned int len) |
---|
1835 | 1893 | { |
---|
1836 | 1894 | struct hci_ufilter uf = { .opcode = 0 }; |
---|
1837 | 1895 | struct sock *sk = sock->sk; |
---|
.. | .. |
---|
1851 | 1909 | |
---|
1852 | 1910 | switch (optname) { |
---|
1853 | 1911 | case HCI_DATA_DIR: |
---|
1854 | | - if (get_user(opt, (int __user *)optval)) { |
---|
| 1912 | + if (copy_from_sockptr(&opt, optval, sizeof(opt))) { |
---|
1855 | 1913 | err = -EFAULT; |
---|
1856 | 1914 | break; |
---|
1857 | 1915 | } |
---|
.. | .. |
---|
1863 | 1921 | break; |
---|
1864 | 1922 | |
---|
1865 | 1923 | case HCI_TIME_STAMP: |
---|
1866 | | - if (get_user(opt, (int __user *)optval)) { |
---|
| 1924 | + if (copy_from_sockptr(&opt, optval, sizeof(opt))) { |
---|
1867 | 1925 | err = -EFAULT; |
---|
1868 | 1926 | break; |
---|
1869 | 1927 | } |
---|
.. | .. |
---|
1885 | 1943 | } |
---|
1886 | 1944 | |
---|
1887 | 1945 | len = min_t(unsigned int, len, sizeof(uf)); |
---|
1888 | | - if (copy_from_user(&uf, optval, len)) { |
---|
| 1946 | + if (copy_from_sockptr(&uf, optval, len)) { |
---|
1889 | 1947 | err = -EFAULT; |
---|
1890 | 1948 | break; |
---|
1891 | 1949 | } |
---|
.. | .. |
---|
1985 | 2043 | return err; |
---|
1986 | 2044 | } |
---|
1987 | 2045 | |
---|
| 2046 | +static void hci_sock_destruct(struct sock *sk) |
---|
| 2047 | +{ |
---|
| 2048 | + skb_queue_purge(&sk->sk_receive_queue); |
---|
| 2049 | + skb_queue_purge(&sk->sk_write_queue); |
---|
| 2050 | +} |
---|
| 2051 | + |
---|
1988 | 2052 | static const struct proto_ops hci_sock_ops = { |
---|
1989 | 2053 | .family = PF_BLUETOOTH, |
---|
1990 | 2054 | .owner = THIS_MODULE, |
---|
.. | .. |
---|
1994 | 2058 | .sendmsg = hci_sock_sendmsg, |
---|
1995 | 2059 | .recvmsg = hci_sock_recvmsg, |
---|
1996 | 2060 | .ioctl = hci_sock_ioctl, |
---|
| 2061 | +#ifdef CONFIG_COMPAT |
---|
| 2062 | + .compat_ioctl = hci_sock_compat_ioctl, |
---|
| 2063 | +#endif |
---|
1997 | 2064 | .poll = datagram_poll, |
---|
1998 | 2065 | .listen = sock_no_listen, |
---|
1999 | 2066 | .shutdown = sock_no_shutdown, |
---|
.. | .. |
---|
2035 | 2102 | |
---|
2036 | 2103 | sock->state = SS_UNCONNECTED; |
---|
2037 | 2104 | sk->sk_state = BT_OPEN; |
---|
| 2105 | + sk->sk_destruct = hci_sock_destruct; |
---|
2038 | 2106 | |
---|
2039 | 2107 | bt_sock_link(&hci_sk_list, sk); |
---|
2040 | 2108 | return 0; |
---|