| .. | .. |
|---|
| 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; |
|---|