diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 985366c36f48..7bba469b6828 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -770,17 +770,21 @@ static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol) | |||
770 | return 0; | 770 | return 0; |
771 | } | 771 | } |
772 | 772 | ||
773 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | 773 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
774 | { | 774 | { |
775 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; | ||
776 | struct sock *sk = sock->sk; | 775 | struct sock *sk = sock->sk; |
777 | int err = 0; | 776 | struct sockaddr_l2 la; |
777 | int len, err = 0; | ||
778 | 778 | ||
779 | BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm); | 779 | BT_DBG("sk %p", sk); |
780 | 780 | ||
781 | if (!addr || addr->sa_family != AF_BLUETOOTH) | 781 | if (!addr || addr->sa_family != AF_BLUETOOTH) |
782 | return -EINVAL; | 782 | return -EINVAL; |
783 | 783 | ||
784 | memset(&la, 0, sizeof(la)); | ||
785 | len = min_t(unsigned int, sizeof(la), alen); | ||
786 | memcpy(&la, addr, len); | ||
787 | |||
784 | lock_sock(sk); | 788 | lock_sock(sk); |
785 | 789 | ||
786 | if (sk->sk_state != BT_OPEN) { | 790 | if (sk->sk_state != BT_OPEN) { |
@@ -788,7 +792,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_ | |||
788 | goto done; | 792 | goto done; |
789 | } | 793 | } |
790 | 794 | ||
791 | if (la->l2_psm && btohs(la->l2_psm) < 0x1001 && | 795 | if (la.l2_psm && btohs(la.l2_psm) < 0x1001 && |
792 | !capable(CAP_NET_BIND_SERVICE)) { | 796 | !capable(CAP_NET_BIND_SERVICE)) { |
793 | err = -EACCES; | 797 | err = -EACCES; |
794 | goto done; | 798 | goto done; |
@@ -796,16 +800,16 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_ | |||
796 | 800 | ||
797 | write_lock_bh(&l2cap_sk_list.lock); | 801 | write_lock_bh(&l2cap_sk_list.lock); |
798 | 802 | ||
799 | if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) { | 803 | if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) { |
800 | err = -EADDRINUSE; | 804 | err = -EADDRINUSE; |
801 | } else { | 805 | } else { |
802 | /* Save source address */ | 806 | /* Save source address */ |
803 | bacpy(&bt_sk(sk)->src, &la->l2_bdaddr); | 807 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); |
804 | l2cap_pi(sk)->psm = la->l2_psm; | 808 | l2cap_pi(sk)->psm = la.l2_psm; |
805 | l2cap_pi(sk)->sport = la->l2_psm; | 809 | l2cap_pi(sk)->sport = la.l2_psm; |
806 | sk->sk_state = BT_BOUND; | 810 | sk->sk_state = BT_BOUND; |
807 | 811 | ||
808 | if (btohs(la->l2_psm) == 0x0001 || btohs(la->l2_psm) == 0x0003) | 812 | if (btohs(la.l2_psm) == 0x0001 || btohs(la.l2_psm) == 0x0003) |
809 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | 813 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; |
810 | } | 814 | } |
811 | 815 | ||
@@ -826,7 +830,8 @@ static int l2cap_do_connect(struct sock *sk) | |||
826 | __u8 auth_type; | 830 | __u8 auth_type; |
827 | int err = 0; | 831 | int err = 0; |
828 | 832 | ||
829 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); | 833 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), |
834 | l2cap_pi(sk)->psm); | ||
830 | 835 | ||
831 | if (!(hdev = hci_get_route(dst, src))) | 836 | if (!(hdev = hci_get_route(dst, src))) |
832 | return -EHOSTUNREACH; | 837 | return -EHOSTUNREACH; |
@@ -906,20 +911,24 @@ done: | |||
906 | 911 | ||
907 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) | 912 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) |
908 | { | 913 | { |
909 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; | ||
910 | struct sock *sk = sock->sk; | 914 | struct sock *sk = sock->sk; |
911 | int err = 0; | 915 | struct sockaddr_l2 la; |
916 | int len, err = 0; | ||
912 | 917 | ||
913 | lock_sock(sk); | 918 | lock_sock(sk); |
914 | 919 | ||
915 | BT_DBG("sk %p", sk); | 920 | BT_DBG("sk %p", sk); |
916 | 921 | ||
917 | if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) { | 922 | if (!addr || addr->sa_family != AF_BLUETOOTH) { |
918 | err = -EINVAL; | 923 | err = -EINVAL; |
919 | goto done; | 924 | goto done; |
920 | } | 925 | } |
921 | 926 | ||
922 | if (sk->sk_type == SOCK_SEQPACKET && !la->l2_psm) { | 927 | memset(&la, 0, sizeof(la)); |
928 | len = min_t(unsigned int, sizeof(la), alen); | ||
929 | memcpy(&la, addr, len); | ||
930 | |||
931 | if (sk->sk_type == SOCK_SEQPACKET && !la.l2_psm) { | ||
923 | err = -EINVAL; | 932 | err = -EINVAL; |
924 | goto done; | 933 | goto done; |
925 | } | 934 | } |
@@ -946,8 +955,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
946 | } | 955 | } |
947 | 956 | ||
948 | /* Set destination address and psm */ | 957 | /* Set destination address and psm */ |
949 | bacpy(&bt_sk(sk)->dst, &la->l2_bdaddr); | 958 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); |
950 | l2cap_pi(sk)->psm = la->l2_psm; | 959 | l2cap_pi(sk)->psm = la.l2_psm; |
951 | 960 | ||
952 | if ((err = l2cap_do_connect(sk))) | 961 | if ((err = l2cap_do_connect(sk))) |
953 | goto done; | 962 | goto done; |
@@ -1071,12 +1080,16 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l | |||
1071 | addr->sa_family = AF_BLUETOOTH; | 1080 | addr->sa_family = AF_BLUETOOTH; |
1072 | *len = sizeof(struct sockaddr_l2); | 1081 | *len = sizeof(struct sockaddr_l2); |
1073 | 1082 | ||
1074 | if (peer) | 1083 | if (peer) { |
1084 | la->l2_psm = l2cap_pi(sk)->psm; | ||
1075 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); | 1085 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); |
1076 | else | 1086 | la->l2_cid = htobs(l2cap_pi(sk)->dcid); |
1087 | } else { | ||
1088 | la->l2_psm = l2cap_pi(sk)->sport; | ||
1077 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); | 1089 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); |
1090 | la->l2_cid = htobs(l2cap_pi(sk)->scid); | ||
1091 | } | ||
1078 | 1092 | ||
1079 | la->l2_psm = l2cap_pi(sk)->psm; | ||
1080 | return 0; | 1093 | return 0; |
1081 | } | 1094 | } |
1082 | 1095 | ||
@@ -1208,7 +1221,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us | |||
1208 | { | 1221 | { |
1209 | struct sock *sk = sock->sk; | 1222 | struct sock *sk = sock->sk; |
1210 | struct l2cap_options opts; | 1223 | struct l2cap_options opts; |
1211 | int err = 0, len; | 1224 | int len, err = 0; |
1212 | u32 opt; | 1225 | u32 opt; |
1213 | 1226 | ||
1214 | BT_DBG("sk %p", sk); | 1227 | BT_DBG("sk %p", sk); |