diff options
Diffstat (limited to 'net/bluetooth/rfcomm')
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 43 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 37 |
2 files changed, 37 insertions, 43 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 5759bb7054f..41b3a092841 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -62,7 +62,6 @@ static DEFINE_MUTEX(rfcomm_mutex); | |||
62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) | 62 | #define rfcomm_lock() mutex_lock(&rfcomm_mutex) |
63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) | 63 | #define rfcomm_unlock() mutex_unlock(&rfcomm_mutex) |
64 | 64 | ||
65 | static unsigned long rfcomm_event; | ||
66 | 65 | ||
67 | static LIST_HEAD(session_list); | 66 | static LIST_HEAD(session_list); |
68 | 67 | ||
@@ -120,7 +119,6 @@ static inline void rfcomm_schedule(void) | |||
120 | { | 119 | { |
121 | if (!rfcomm_thread) | 120 | if (!rfcomm_thread) |
122 | return; | 121 | return; |
123 | set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
124 | wake_up_process(rfcomm_thread); | 122 | wake_up_process(rfcomm_thread); |
125 | } | 123 | } |
126 | 124 | ||
@@ -466,7 +464,6 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) | |||
466 | 464 | ||
467 | switch (d->state) { | 465 | switch (d->state) { |
468 | case BT_CONNECT: | 466 | case BT_CONNECT: |
469 | case BT_CONFIG: | ||
470 | if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { | 467 | if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { |
471 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); | 468 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); |
472 | rfcomm_schedule(); | 469 | rfcomm_schedule(); |
@@ -669,6 +666,9 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err) | |||
669 | 666 | ||
670 | BT_DBG("session %p state %ld err %d", s, s->state, err); | 667 | BT_DBG("session %p state %ld err %d", s, s->state, err); |
671 | 668 | ||
669 | if (s->state == BT_CLOSED) | ||
670 | return; | ||
671 | |||
672 | rfcomm_session_hold(s); | 672 | rfcomm_session_hold(s); |
673 | 673 | ||
674 | s->state = BT_CLOSED; | 674 | s->state = BT_CLOSED; |
@@ -681,6 +681,12 @@ static void rfcomm_session_close(struct rfcomm_session *s, int err) | |||
681 | } | 681 | } |
682 | 682 | ||
683 | rfcomm_session_clear_timer(s); | 683 | rfcomm_session_clear_timer(s); |
684 | |||
685 | /* Drop reference for incoming sessions */ | ||
686 | if (!s->initiator) | ||
687 | if (list_empty(&s->dlcs)) | ||
688 | rfcomm_session_put(s); | ||
689 | |||
684 | rfcomm_session_put(s); | 690 | rfcomm_session_put(s); |
685 | } | 691 | } |
686 | 692 | ||
@@ -1161,12 +1167,7 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) | |||
1161 | break; | 1167 | break; |
1162 | 1168 | ||
1163 | case BT_DISCONN: | 1169 | case BT_DISCONN: |
1164 | /* When socket is closed and we are not RFCOMM | 1170 | rfcomm_session_close(s, 0); |
1165 | * initiator rfcomm_process_rx already calls | ||
1166 | * rfcomm_session_put() */ | ||
1167 | if (s->sock->sk->sk_state != BT_CLOSED) | ||
1168 | if (list_empty(&s->dlcs)) | ||
1169 | rfcomm_session_put(s); | ||
1170 | break; | 1171 | break; |
1171 | } | 1172 | } |
1172 | } | 1173 | } |
@@ -1197,7 +1198,6 @@ static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci) | |||
1197 | else | 1198 | else |
1198 | err = ECONNRESET; | 1199 | err = ECONNRESET; |
1199 | 1200 | ||
1200 | s->state = BT_CLOSED; | ||
1201 | rfcomm_session_close(s, err); | 1201 | rfcomm_session_close(s, err); |
1202 | } | 1202 | } |
1203 | return 0; | 1203 | return 0; |
@@ -1232,7 +1232,6 @@ static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci) | |||
1232 | else | 1232 | else |
1233 | err = ECONNRESET; | 1233 | err = ECONNRESET; |
1234 | 1234 | ||
1235 | s->state = BT_CLOSED; | ||
1236 | rfcomm_session_close(s, err); | 1235 | rfcomm_session_close(s, err); |
1237 | } | 1236 | } |
1238 | 1237 | ||
@@ -1858,12 +1857,8 @@ static inline void rfcomm_process_rx(struct rfcomm_session *s) | |||
1858 | rfcomm_recv_frame(s, skb); | 1857 | rfcomm_recv_frame(s, skb); |
1859 | } | 1858 | } |
1860 | 1859 | ||
1861 | if (sk->sk_state == BT_CLOSED) { | 1860 | if (sk->sk_state == BT_CLOSED) |
1862 | if (!s->initiator) | ||
1863 | rfcomm_session_put(s); | ||
1864 | |||
1865 | rfcomm_session_close(s, sk->sk_err); | 1861 | rfcomm_session_close(s, sk->sk_err); |
1866 | } | ||
1867 | } | 1862 | } |
1868 | 1863 | ||
1869 | static inline void rfcomm_accept_connection(struct rfcomm_session *s) | 1864 | static inline void rfcomm_accept_connection(struct rfcomm_session *s) |
@@ -1918,7 +1913,6 @@ static inline void rfcomm_check_connection(struct rfcomm_session *s) | |||
1918 | break; | 1913 | break; |
1919 | 1914 | ||
1920 | case BT_CLOSED: | 1915 | case BT_CLOSED: |
1921 | s->state = BT_CLOSED; | ||
1922 | rfcomm_session_close(s, sk->sk_err); | 1916 | rfcomm_session_close(s, sk->sk_err); |
1923 | break; | 1917 | break; |
1924 | } | 1918 | } |
@@ -2038,19 +2032,18 @@ static int rfcomm_run(void *unused) | |||
2038 | 2032 | ||
2039 | rfcomm_add_listener(BDADDR_ANY); | 2033 | rfcomm_add_listener(BDADDR_ANY); |
2040 | 2034 | ||
2041 | while (!kthread_should_stop()) { | 2035 | while (1) { |
2042 | set_current_state(TASK_INTERRUPTIBLE); | 2036 | set_current_state(TASK_INTERRUPTIBLE); |
2043 | if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) { | 2037 | |
2044 | /* No pending events. Let's sleep. | 2038 | if (kthread_should_stop()) |
2045 | * Incoming connections and data will wake us up. */ | 2039 | break; |
2046 | schedule(); | ||
2047 | } | ||
2048 | set_current_state(TASK_RUNNING); | ||
2049 | 2040 | ||
2050 | /* Process stuff */ | 2041 | /* Process stuff */ |
2051 | clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event); | ||
2052 | rfcomm_process_sessions(); | 2042 | rfcomm_process_sessions(); |
2043 | |||
2044 | schedule(); | ||
2053 | } | 2045 | } |
2046 | __set_current_state(TASK_RUNNING); | ||
2054 | 2047 | ||
2055 | rfcomm_kill_listener(); | 2048 | rfcomm_kill_listener(); |
2056 | 2049 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 1b10727ce52..5417f612732 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/debugfs.h> | 43 | #include <linux/debugfs.h> |
44 | #include <linux/seq_file.h> | 44 | #include <linux/seq_file.h> |
45 | #include <linux/security.h> | ||
45 | #include <net/sock.h> | 46 | #include <net/sock.h> |
46 | 47 | ||
47 | #include <asm/system.h> | 48 | #include <asm/system.h> |
@@ -264,6 +265,8 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent) | |||
264 | 265 | ||
265 | pi->sec_level = rfcomm_pi(parent)->sec_level; | 266 | pi->sec_level = rfcomm_pi(parent)->sec_level; |
266 | pi->role_switch = rfcomm_pi(parent)->role_switch; | 267 | pi->role_switch = rfcomm_pi(parent)->role_switch; |
268 | |||
269 | security_sk_clone(parent, sk); | ||
267 | } else { | 270 | } else { |
268 | pi->dlc->defer_setup = 0; | 271 | pi->dlc->defer_setup = 0; |
269 | 272 | ||
@@ -485,11 +488,6 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
485 | 488 | ||
486 | lock_sock(sk); | 489 | lock_sock(sk); |
487 | 490 | ||
488 | if (sk->sk_state != BT_LISTEN) { | ||
489 | err = -EBADFD; | ||
490 | goto done; | ||
491 | } | ||
492 | |||
493 | if (sk->sk_type != SOCK_STREAM) { | 491 | if (sk->sk_type != SOCK_STREAM) { |
494 | err = -EINVAL; | 492 | err = -EINVAL; |
495 | goto done; | 493 | goto done; |
@@ -501,19 +499,20 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
501 | 499 | ||
502 | /* Wait for an incoming connection. (wake-one). */ | 500 | /* Wait for an incoming connection. (wake-one). */ |
503 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | 501 | add_wait_queue_exclusive(sk_sleep(sk), &wait); |
504 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | 502 | while (1) { |
505 | set_current_state(TASK_INTERRUPTIBLE); | 503 | set_current_state(TASK_INTERRUPTIBLE); |
506 | if (!timeo) { | 504 | |
507 | err = -EAGAIN; | 505 | if (sk->sk_state != BT_LISTEN) { |
506 | err = -EBADFD; | ||
508 | break; | 507 | break; |
509 | } | 508 | } |
510 | 509 | ||
511 | release_sock(sk); | 510 | nsk = bt_accept_dequeue(sk, newsock); |
512 | timeo = schedule_timeout(timeo); | 511 | if (nsk) |
513 | lock_sock(sk); | 512 | break; |
514 | 513 | ||
515 | if (sk->sk_state != BT_LISTEN) { | 514 | if (!timeo) { |
516 | err = -EBADFD; | 515 | err = -EAGAIN; |
517 | break; | 516 | break; |
518 | } | 517 | } |
519 | 518 | ||
@@ -521,8 +520,12 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f | |||
521 | err = sock_intr_errno(timeo); | 520 | err = sock_intr_errno(timeo); |
522 | break; | 521 | break; |
523 | } | 522 | } |
523 | |||
524 | release_sock(sk); | ||
525 | timeo = schedule_timeout(timeo); | ||
526 | lock_sock(sk); | ||
524 | } | 527 | } |
525 | set_current_state(TASK_RUNNING); | 528 | __set_current_state(TASK_RUNNING); |
526 | remove_wait_queue(sk_sleep(sk), &wait); | 529 | remove_wait_queue(sk_sleep(sk), &wait); |
527 | 530 | ||
528 | if (err) | 531 | if (err) |
@@ -679,7 +682,8 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
679 | { | 682 | { |
680 | struct sock *sk = sock->sk; | 683 | struct sock *sk = sock->sk; |
681 | struct bt_security sec; | 684 | struct bt_security sec; |
682 | int len, err = 0; | 685 | int err = 0; |
686 | size_t len; | ||
683 | u32 opt; | 687 | u32 opt; |
684 | 688 | ||
685 | BT_DBG("sk %p", sk); | 689 | BT_DBG("sk %p", sk); |
@@ -741,7 +745,6 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
741 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | 745 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) |
742 | { | 746 | { |
743 | struct sock *sk = sock->sk; | 747 | struct sock *sk = sock->sk; |
744 | struct sock *l2cap_sk; | ||
745 | struct rfcomm_conninfo cinfo; | 748 | struct rfcomm_conninfo cinfo; |
746 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; | 749 | struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; |
747 | int len, err = 0; | 750 | int len, err = 0; |
@@ -786,8 +789,6 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
786 | break; | 789 | break; |
787 | } | 790 | } |
788 | 791 | ||
789 | l2cap_sk = rfcomm_pi(sk)->dlc->session->sock->sk; | ||
790 | |||
791 | memset(&cinfo, 0, sizeof(cinfo)); | 792 | memset(&cinfo, 0, sizeof(cinfo)); |
792 | cinfo.hci_handle = conn->hcon->handle; | 793 | cinfo.hci_handle = conn->hcon->handle; |
793 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); | 794 | memcpy(cinfo.dev_class, conn->hcon->dev_class, 3); |