diff options
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 37 |
1 files changed, 19 insertions, 18 deletions
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); |