.. | .. |
---|
888 | 888 | } |
---|
889 | 889 | |
---|
890 | 890 | sock_orphan(sk); |
---|
891 | | - |
---|
892 | | - skb_queue_purge(&sk->sk_receive_queue); |
---|
893 | | - skb_queue_purge(&sk->sk_write_queue); |
---|
894 | | - |
---|
895 | 891 | release_sock(sk); |
---|
896 | 892 | sock_put(sk); |
---|
897 | 893 | return 0; |
---|
.. | .. |
---|
984 | 980 | |
---|
985 | 981 | BT_DBG("cmd %x arg %lx", cmd, arg); |
---|
986 | 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 | + |
---|
987 | 1011 | lock_sock(sk); |
---|
988 | 1012 | |
---|
989 | 1013 | if (hci_pi(sk)->channel != HCI_CHANNEL_RAW) { |
---|
.. | .. |
---|
1000 | 1024 | if (hci_sock_gen_cookie(sk)) { |
---|
1001 | 1025 | struct sk_buff *skb; |
---|
1002 | 1026 | |
---|
1003 | | - 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)) |
---|
1004 | 1035 | hci_sock_set_flag(sk, HCI_SOCK_TRUSTED); |
---|
1005 | 1036 | |
---|
1006 | 1037 | /* Send event to monitor */ |
---|
.. | .. |
---|
2012 | 2043 | return err; |
---|
2013 | 2044 | } |
---|
2014 | 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 | + |
---|
2015 | 2052 | static const struct proto_ops hci_sock_ops = { |
---|
2016 | 2053 | .family = PF_BLUETOOTH, |
---|
2017 | 2054 | .owner = THIS_MODULE, |
---|
.. | .. |
---|
2065 | 2102 | |
---|
2066 | 2103 | sock->state = SS_UNCONNECTED; |
---|
2067 | 2104 | sk->sk_state = BT_OPEN; |
---|
| 2105 | + sk->sk_destruct = hci_sock_destruct; |
---|
2068 | 2106 | |
---|
2069 | 2107 | bt_sock_link(&hci_sk_list, sk); |
---|
2070 | 2108 | return 0; |
---|