diff options
Diffstat (limited to 'net/bluetooth/af_bluetooth.c')
-rw-r--r-- | net/bluetooth/af_bluetooth.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index 8add9b49991..7c73a10d7ed 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -40,6 +40,15 @@ | |||
40 | 40 | ||
41 | #include <net/bluetooth/bluetooth.h> | 41 | #include <net/bluetooth/bluetooth.h> |
42 | 42 | ||
43 | #ifdef CONFIG_ANDROID_PARANOID_NETWORK | ||
44 | #include <linux/android_aid.h> | ||
45 | #endif | ||
46 | |||
47 | #ifndef CONFIG_BT_SOCK_DEBUG | ||
48 | #undef BT_DBG | ||
49 | #define BT_DBG(D...) | ||
50 | #endif | ||
51 | |||
43 | #define VERSION "2.16" | 52 | #define VERSION "2.16" |
44 | 53 | ||
45 | /* Bluetooth sockets */ | 54 | /* Bluetooth sockets */ |
@@ -125,11 +134,40 @@ int bt_sock_unregister(int proto) | |||
125 | } | 134 | } |
126 | EXPORT_SYMBOL(bt_sock_unregister); | 135 | EXPORT_SYMBOL(bt_sock_unregister); |
127 | 136 | ||
137 | #ifdef CONFIG_ANDROID_PARANOID_NETWORK | ||
138 | static inline int current_has_bt_admin(void) | ||
139 | { | ||
140 | return (!current_euid() || in_egroup_p(AID_NET_BT_ADMIN)); | ||
141 | } | ||
142 | |||
143 | static inline int current_has_bt(void) | ||
144 | { | ||
145 | return (current_has_bt_admin() || in_egroup_p(AID_NET_BT)); | ||
146 | } | ||
147 | # else | ||
148 | static inline int current_has_bt_admin(void) | ||
149 | { | ||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | static inline int current_has_bt(void) | ||
154 | { | ||
155 | return 1; | ||
156 | } | ||
157 | #endif | ||
158 | |||
128 | static int bt_sock_create(struct net *net, struct socket *sock, int proto, | 159 | static int bt_sock_create(struct net *net, struct socket *sock, int proto, |
129 | int kern) | 160 | int kern) |
130 | { | 161 | { |
131 | int err; | 162 | int err; |
132 | 163 | ||
164 | if (proto == BTPROTO_RFCOMM || proto == BTPROTO_SCO || | ||
165 | proto == BTPROTO_L2CAP) { | ||
166 | if (!current_has_bt()) | ||
167 | return -EPERM; | ||
168 | } else if (!current_has_bt_admin()) | ||
169 | return -EPERM; | ||
170 | |||
133 | if (net != &init_net) | 171 | if (net != &init_net) |
134 | return -EAFNOSUPPORT; | 172 | return -EAFNOSUPPORT; |
135 | 173 | ||
@@ -494,9 +532,8 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
494 | BT_DBG("sk %p", sk); | 532 | BT_DBG("sk %p", sk); |
495 | 533 | ||
496 | add_wait_queue(sk_sleep(sk), &wait); | 534 | add_wait_queue(sk_sleep(sk), &wait); |
535 | set_current_state(TASK_INTERRUPTIBLE); | ||
497 | while (sk->sk_state != state) { | 536 | while (sk->sk_state != state) { |
498 | set_current_state(TASK_INTERRUPTIBLE); | ||
499 | |||
500 | if (!timeo) { | 537 | if (!timeo) { |
501 | err = -EINPROGRESS; | 538 | err = -EINPROGRESS; |
502 | break; | 539 | break; |
@@ -510,12 +547,13 @@ int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo) | |||
510 | release_sock(sk); | 547 | release_sock(sk); |
511 | timeo = schedule_timeout(timeo); | 548 | timeo = schedule_timeout(timeo); |
512 | lock_sock(sk); | 549 | lock_sock(sk); |
550 | set_current_state(TASK_INTERRUPTIBLE); | ||
513 | 551 | ||
514 | err = sock_error(sk); | 552 | err = sock_error(sk); |
515 | if (err) | 553 | if (err) |
516 | break; | 554 | break; |
517 | } | 555 | } |
518 | set_current_state(TASK_RUNNING); | 556 | __set_current_state(TASK_RUNNING); |
519 | remove_wait_queue(sk_sleep(sk), &wait); | 557 | remove_wait_queue(sk_sleep(sk), &wait); |
520 | return err; | 558 | return err; |
521 | } | 559 | } |