diff options
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
-rw-r--r-- | net/bluetooth/rfcomm/sock.c | 189 |
1 files changed, 179 insertions, 10 deletions
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index d3fc6fca38d0..7f482784e9f7 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -261,12 +261,19 @@ static void rfcomm_sock_init(struct sock *sk, struct sock *parent) | |||
261 | 261 | ||
262 | if (parent) { | 262 | if (parent) { |
263 | sk->sk_type = parent->sk_type; | 263 | sk->sk_type = parent->sk_type; |
264 | pi->link_mode = rfcomm_pi(parent)->link_mode; | 264 | pi->dlc->defer_setup = bt_sk(parent)->defer_setup; |
265 | |||
266 | pi->sec_level = rfcomm_pi(parent)->sec_level; | ||
267 | pi->role_switch = rfcomm_pi(parent)->role_switch; | ||
265 | } else { | 268 | } else { |
266 | pi->link_mode = 0; | 269 | pi->dlc->defer_setup = 0; |
270 | |||
271 | pi->sec_level = BT_SECURITY_LOW; | ||
272 | pi->role_switch = 0; | ||
267 | } | 273 | } |
268 | 274 | ||
269 | pi->dlc->link_mode = pi->link_mode; | 275 | pi->dlc->sec_level = pi->sec_level; |
276 | pi->dlc->role_switch = pi->role_switch; | ||
270 | } | 277 | } |
271 | 278 | ||
272 | static struct proto rfcomm_proto = { | 279 | static struct proto rfcomm_proto = { |
@@ -406,7 +413,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a | |||
406 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); | 413 | bacpy(&bt_sk(sk)->dst, &sa->rc_bdaddr); |
407 | rfcomm_pi(sk)->channel = sa->rc_channel; | 414 | rfcomm_pi(sk)->channel = sa->rc_channel; |
408 | 415 | ||
409 | d->link_mode = rfcomm_pi(sk)->link_mode; | 416 | d->sec_level = rfcomm_pi(sk)->sec_level; |
417 | d->role_switch = rfcomm_pi(sk)->role_switch; | ||
410 | 418 | ||
411 | err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); | 419 | err = rfcomm_dlc_open(d, &bt_sk(sk)->src, &sa->rc_bdaddr, sa->rc_channel); |
412 | if (!err) | 420 | if (!err) |
@@ -554,6 +562,9 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
554 | struct sk_buff *skb; | 562 | struct sk_buff *skb; |
555 | int sent = 0; | 563 | int sent = 0; |
556 | 564 | ||
565 | if (test_bit(RFCOMM_DEFER_SETUP, &d->flags)) | ||
566 | return -ENOTCONN; | ||
567 | |||
557 | if (msg->msg_flags & MSG_OOB) | 568 | if (msg->msg_flags & MSG_OOB) |
558 | return -EOPNOTSUPP; | 569 | return -EOPNOTSUPP; |
559 | 570 | ||
@@ -570,8 +581,11 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
570 | 581 | ||
571 | skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, | 582 | skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, |
572 | msg->msg_flags & MSG_DONTWAIT, &err); | 583 | msg->msg_flags & MSG_DONTWAIT, &err); |
573 | if (!skb) | 584 | if (!skb) { |
585 | if (sent == 0) | ||
586 | sent = err; | ||
574 | break; | 587 | break; |
588 | } | ||
575 | skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE); | 589 | skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE); |
576 | 590 | ||
577 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); | 591 | err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); |
@@ -630,10 +644,16 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
630 | struct msghdr *msg, size_t size, int flags) | 644 | struct msghdr *msg, size_t size, int flags) |
631 | { | 645 | { |
632 | struct sock *sk = sock->sk; | 646 | struct sock *sk = sock->sk; |
647 | struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; | ||
633 | int err = 0; | 648 | int err = 0; |
634 | size_t target, copied = 0; | 649 | size_t target, copied = 0; |
635 | long timeo; | 650 | long timeo; |
636 | 651 | ||
652 | if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { | ||
653 | rfcomm_dlc_accept(d); | ||
654 | return 0; | ||
655 | } | ||
656 | |||
637 | if (flags & MSG_OOB) | 657 | if (flags & MSG_OOB) |
638 | return -EOPNOTSUPP; | 658 | return -EOPNOTSUPP; |
639 | 659 | ||
@@ -710,7 +730,7 @@ out: | |||
710 | return copied ? : err; | 730 | return copied ? : err; |
711 | } | 731 | } |
712 | 732 | ||
713 | static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) | 733 | static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, int optlen) |
714 | { | 734 | { |
715 | struct sock *sk = sock->sk; | 735 | struct sock *sk = sock->sk; |
716 | int err = 0; | 736 | int err = 0; |
@@ -727,7 +747,14 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
727 | break; | 747 | break; |
728 | } | 748 | } |
729 | 749 | ||
730 | rfcomm_pi(sk)->link_mode = opt; | 750 | if (opt & RFCOMM_LM_AUTH) |
751 | rfcomm_pi(sk)->sec_level = BT_SECURITY_LOW; | ||
752 | if (opt & RFCOMM_LM_ENCRYPT) | ||
753 | rfcomm_pi(sk)->sec_level = BT_SECURITY_MEDIUM; | ||
754 | if (opt & RFCOMM_LM_SECURE) | ||
755 | rfcomm_pi(sk)->sec_level = BT_SECURITY_HIGH; | ||
756 | |||
757 | rfcomm_pi(sk)->role_switch = (opt & RFCOMM_LM_MASTER); | ||
731 | break; | 758 | break; |
732 | 759 | ||
733 | default: | 760 | default: |
@@ -739,12 +766,76 @@ static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, c | |||
739 | return err; | 766 | return err; |
740 | } | 767 | } |
741 | 768 | ||
742 | static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | 769 | static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) |
770 | { | ||
771 | struct sock *sk = sock->sk; | ||
772 | struct bt_security sec; | ||
773 | int len, err = 0; | ||
774 | u32 opt; | ||
775 | |||
776 | BT_DBG("sk %p", sk); | ||
777 | |||
778 | if (level == SOL_RFCOMM) | ||
779 | return rfcomm_sock_setsockopt_old(sock, optname, optval, optlen); | ||
780 | |||
781 | if (level != SOL_BLUETOOTH) | ||
782 | return -ENOPROTOOPT; | ||
783 | |||
784 | lock_sock(sk); | ||
785 | |||
786 | switch (optname) { | ||
787 | case BT_SECURITY: | ||
788 | if (sk->sk_type != SOCK_STREAM) { | ||
789 | err = -EINVAL; | ||
790 | break; | ||
791 | } | ||
792 | |||
793 | sec.level = BT_SECURITY_LOW; | ||
794 | |||
795 | len = min_t(unsigned int, sizeof(sec), optlen); | ||
796 | if (copy_from_user((char *) &sec, optval, len)) { | ||
797 | err = -EFAULT; | ||
798 | break; | ||
799 | } | ||
800 | |||
801 | if (sec.level > BT_SECURITY_HIGH) { | ||
802 | err = -EINVAL; | ||
803 | break; | ||
804 | } | ||
805 | |||
806 | rfcomm_pi(sk)->sec_level = sec.level; | ||
807 | break; | ||
808 | |||
809 | case BT_DEFER_SETUP: | ||
810 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | ||
811 | err = -EINVAL; | ||
812 | break; | ||
813 | } | ||
814 | |||
815 | if (get_user(opt, (u32 __user *) optval)) { | ||
816 | err = -EFAULT; | ||
817 | break; | ||
818 | } | ||
819 | |||
820 | bt_sk(sk)->defer_setup = opt; | ||
821 | break; | ||
822 | |||
823 | default: | ||
824 | err = -ENOPROTOOPT; | ||
825 | break; | ||
826 | } | ||
827 | |||
828 | release_sock(sk); | ||
829 | return err; | ||
830 | } | ||
831 | |||
832 | static int rfcomm_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | ||
743 | { | 833 | { |
744 | struct sock *sk = sock->sk; | 834 | struct sock *sk = sock->sk; |
745 | struct sock *l2cap_sk; | 835 | struct sock *l2cap_sk; |
746 | struct rfcomm_conninfo cinfo; | 836 | struct rfcomm_conninfo cinfo; |
747 | int len, err = 0; | 837 | int len, err = 0; |
838 | u32 opt; | ||
748 | 839 | ||
749 | BT_DBG("sk %p", sk); | 840 | BT_DBG("sk %p", sk); |
750 | 841 | ||
@@ -755,12 +846,32 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c | |||
755 | 846 | ||
756 | switch (optname) { | 847 | switch (optname) { |
757 | case RFCOMM_LM: | 848 | case RFCOMM_LM: |
758 | if (put_user(rfcomm_pi(sk)->link_mode, (u32 __user *) optval)) | 849 | switch (rfcomm_pi(sk)->sec_level) { |
850 | case BT_SECURITY_LOW: | ||
851 | opt = RFCOMM_LM_AUTH; | ||
852 | break; | ||
853 | case BT_SECURITY_MEDIUM: | ||
854 | opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT; | ||
855 | break; | ||
856 | case BT_SECURITY_HIGH: | ||
857 | opt = RFCOMM_LM_AUTH | RFCOMM_LM_ENCRYPT | | ||
858 | RFCOMM_LM_SECURE; | ||
859 | break; | ||
860 | default: | ||
861 | opt = 0; | ||
862 | break; | ||
863 | } | ||
864 | |||
865 | if (rfcomm_pi(sk)->role_switch) | ||
866 | opt |= RFCOMM_LM_MASTER; | ||
867 | |||
868 | if (put_user(opt, (u32 __user *) optval)) | ||
759 | err = -EFAULT; | 869 | err = -EFAULT; |
760 | break; | 870 | break; |
761 | 871 | ||
762 | case RFCOMM_CONNINFO: | 872 | case RFCOMM_CONNINFO: |
763 | if (sk->sk_state != BT_CONNECTED) { | 873 | if (sk->sk_state != BT_CONNECTED && |
874 | !rfcomm_pi(sk)->dlc->defer_setup) { | ||
764 | err = -ENOTCONN; | 875 | err = -ENOTCONN; |
765 | break; | 876 | break; |
766 | } | 877 | } |
@@ -785,6 +896,60 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c | |||
785 | return err; | 896 | return err; |
786 | } | 897 | } |
787 | 898 | ||
899 | static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | ||
900 | { | ||
901 | struct sock *sk = sock->sk; | ||
902 | struct bt_security sec; | ||
903 | int len, err = 0; | ||
904 | |||
905 | BT_DBG("sk %p", sk); | ||
906 | |||
907 | if (level == SOL_RFCOMM) | ||
908 | return rfcomm_sock_getsockopt_old(sock, optname, optval, optlen); | ||
909 | |||
910 | if (level != SOL_BLUETOOTH) | ||
911 | return -ENOPROTOOPT; | ||
912 | |||
913 | if (get_user(len, optlen)) | ||
914 | return -EFAULT; | ||
915 | |||
916 | lock_sock(sk); | ||
917 | |||
918 | switch (optname) { | ||
919 | case BT_SECURITY: | ||
920 | if (sk->sk_type != SOCK_STREAM) { | ||
921 | err = -EINVAL; | ||
922 | break; | ||
923 | } | ||
924 | |||
925 | sec.level = rfcomm_pi(sk)->sec_level; | ||
926 | |||
927 | len = min_t(unsigned int, len, sizeof(sec)); | ||
928 | if (copy_to_user(optval, (char *) &sec, len)) | ||
929 | err = -EFAULT; | ||
930 | |||
931 | break; | ||
932 | |||
933 | case BT_DEFER_SETUP: | ||
934 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | ||
935 | err = -EINVAL; | ||
936 | break; | ||
937 | } | ||
938 | |||
939 | if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval)) | ||
940 | err = -EFAULT; | ||
941 | |||
942 | break; | ||
943 | |||
944 | default: | ||
945 | err = -ENOPROTOOPT; | ||
946 | break; | ||
947 | } | ||
948 | |||
949 | release_sock(sk); | ||
950 | return err; | ||
951 | } | ||
952 | |||
788 | static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 953 | static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
789 | { | 954 | { |
790 | struct sock *sk __maybe_unused = sock->sk; | 955 | struct sock *sk __maybe_unused = sock->sk; |
@@ -888,6 +1053,10 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc * | |||
888 | 1053 | ||
889 | done: | 1054 | done: |
890 | bh_unlock_sock(parent); | 1055 | bh_unlock_sock(parent); |
1056 | |||
1057 | if (bt_sk(parent)->defer_setup) | ||
1058 | parent->sk_state_change(parent); | ||
1059 | |||
891 | return result; | 1060 | return result; |
892 | } | 1061 | } |
893 | 1062 | ||