diff options
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 3c2d3e4aa2f5..c024e715512f 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -105,13 +105,18 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /* ---- Socket functions ---- */ | 107 | /* ---- Socket functions ---- */ |
108 | static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src) | 108 | static struct sock *__rfcomm_get_listen_sock_by_addr(u8 channel, bdaddr_t *src) |
109 | { | 109 | { |
110 | struct sock *sk = NULL; | 110 | struct sock *sk = NULL; |
111 | 111 | ||
112 | sk_for_each(sk, &rfcomm_sk_list.head) { | 112 | sk_for_each(sk, &rfcomm_sk_list.head) { |
113 | if (rfcomm_pi(sk)->channel == channel && | 113 | if (rfcomm_pi(sk)->channel != channel) |
114 | !bacmp(&rfcomm_pi(sk)->src, src)) | 114 | continue; |
115 | |||
116 | if (bacmp(&rfcomm_pi(sk)->src, src)) | ||
117 | continue; | ||
118 | |||
119 | if (sk->sk_state == BT_BOUND || sk->sk_state == BT_LISTEN) | ||
115 | break; | 120 | break; |
116 | } | 121 | } |
117 | 122 | ||
@@ -331,6 +336,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr | |||
331 | { | 336 | { |
332 | struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; | 337 | struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; |
333 | struct sock *sk = sock->sk; | 338 | struct sock *sk = sock->sk; |
339 | int chan = sa->rc_channel; | ||
334 | int err = 0; | 340 | int err = 0; |
335 | 341 | ||
336 | BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); | 342 | BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); |
@@ -352,12 +358,12 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr | |||
352 | 358 | ||
353 | write_lock(&rfcomm_sk_list.lock); | 359 | write_lock(&rfcomm_sk_list.lock); |
354 | 360 | ||
355 | if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) { | 361 | if (chan && __rfcomm_get_listen_sock_by_addr(chan, &sa->rc_bdaddr)) { |
356 | err = -EADDRINUSE; | 362 | err = -EADDRINUSE; |
357 | } else { | 363 | } else { |
358 | /* Save source address */ | 364 | /* Save source address */ |
359 | bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr); | 365 | bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr); |
360 | rfcomm_pi(sk)->channel = sa->rc_channel; | 366 | rfcomm_pi(sk)->channel = chan; |
361 | sk->sk_state = BT_BOUND; | 367 | sk->sk_state = BT_BOUND; |
362 | } | 368 | } |
363 | 369 | ||
@@ -439,7 +445,7 @@ static int rfcomm_sock_listen(struct socket *sock, int backlog) | |||
439 | write_lock(&rfcomm_sk_list.lock); | 445 | write_lock(&rfcomm_sk_list.lock); |
440 | 446 | ||
441 | for (channel = 1; channel < 31; channel++) | 447 | for (channel = 1; channel < 31; channel++) |
442 | if (!__rfcomm_get_sock_by_addr(channel, src)) { | 448 | if (!__rfcomm_get_listen_sock_by_addr(channel, src)) { |
443 | rfcomm_pi(sk)->channel = channel; | 449 | rfcomm_pi(sk)->channel = channel; |
444 | err = 0; | 450 | err = 0; |
445 | break; | 451 | break; |
@@ -528,6 +534,9 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * | |||
528 | 534 | ||
529 | BT_DBG("sock %p, sk %p", sock, sk); | 535 | BT_DBG("sock %p, sk %p", sock, sk); |
530 | 536 | ||
537 | if (peer && sk->sk_state != BT_CONNECTED) | ||
538 | return -ENOTCONN; | ||
539 | |||
531 | memset(sa, 0, sizeof(*sa)); | 540 | memset(sa, 0, sizeof(*sa)); |
532 | sa->rc_family = AF_BLUETOOTH; | 541 | sa->rc_family = AF_BLUETOOTH; |
533 | sa->rc_channel = rfcomm_pi(sk)->channel; | 542 | sa->rc_channel = rfcomm_pi(sk)->channel; |
@@ -648,6 +657,11 @@ static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __u | |||
648 | break; | 657 | break; |
649 | } | 658 | } |
650 | 659 | ||
660 | if (opt & RFCOMM_LM_FIPS) { | ||
661 | err = -EINVAL; | ||
662 | break; | ||
663 | } | ||
664 | |||
651 | if (opt & RFCOMM_LM_AUTH) | 665 | if (opt & RFCOMM_LM_AUTH) |
652 | rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW; | 666 | rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW; |
653 | if (opt & RFCOMM_LM_ENCRYPT) | 667 | if (opt & RFCOMM_LM_ENCRYPT) |
@@ -762,7 +776,11 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
762 | break; | 776 | break; |
763 | case BT_SECURITY_HIGH: | 777 | case BT_SECURITY_HIGH: |
764 | opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | | 778 | opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | |
765 | RFCOMM_LM_SECURE; | 779 | RFCOMM_LM_SECURE; |
780 | break; | ||
781 | case BT_SECURITY_FIPS: | ||
782 | opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | | ||
783 | RFCOMM_LM_SECURE | RFCOMM_LM_FIPS; | ||
766 | break; | 784 | break; |
767 | default: | 785 | default: |
768 | opt = 0; | 786 | opt = 0; |
@@ -774,6 +792,7 @@ static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __u | |||
774 | 792 | ||
775 | if (put_user(opt, (u32 __user *) optval)) | 793 | if (put_user(opt, (u32 __user *) optval)) |
776 | err = -EFAULT; | 794 | err = -EFAULT; |
795 | |||
777 | break; | 796 | break; |
778 | 797 | ||
779 | case RFCOMM_CONNINFO: | 798 | case RFCOMM_CONNINFO: |