diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 70 |
1 files changed, 43 insertions, 27 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 77e6715d7898..f6a82f203fd2 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -40,10 +40,10 @@ | |||
40 | #include <linux/skbuff.h> | 40 | #include <linux/skbuff.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/device.h> | 42 | #include <linux/device.h> |
43 | #include <linux/uaccess.h> | ||
43 | #include <net/sock.h> | 44 | #include <net/sock.h> |
44 | 45 | ||
45 | #include <asm/system.h> | 46 | #include <asm/system.h> |
46 | #include <asm/uaccess.h> | ||
47 | #include <asm/unaligned.h> | 47 | #include <asm/unaligned.h> |
48 | 48 | ||
49 | #include <net/bluetooth/bluetooth.h> | 49 | #include <net/bluetooth/bluetooth.h> |
@@ -134,7 +134,8 @@ static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16 | |||
134 | struct sock *s; | 134 | struct sock *s; |
135 | read_lock(&l->lock); | 135 | read_lock(&l->lock); |
136 | s = __l2cap_get_chan_by_scid(l, cid); | 136 | s = __l2cap_get_chan_by_scid(l, cid); |
137 | if (s) bh_lock_sock(s); | 137 | if (s) |
138 | bh_lock_sock(s); | ||
138 | read_unlock(&l->lock); | 139 | read_unlock(&l->lock); |
139 | return s; | 140 | return s; |
140 | } | 141 | } |
@@ -154,7 +155,8 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8 | |||
154 | struct sock *s; | 155 | struct sock *s; |
155 | read_lock(&l->lock); | 156 | read_lock(&l->lock); |
156 | s = __l2cap_get_chan_by_ident(l, ident); | 157 | s = __l2cap_get_chan_by_ident(l, ident); |
157 | if (s) bh_lock_sock(s); | 158 | if (s) |
159 | bh_lock_sock(s); | ||
158 | read_unlock(&l->lock); | 160 | read_unlock(&l->lock); |
159 | return s; | 161 | return s; |
160 | } | 162 | } |
@@ -164,7 +166,7 @@ static u16 l2cap_alloc_cid(struct l2cap_chan_list *l) | |||
164 | u16 cid = L2CAP_CID_DYN_START; | 166 | u16 cid = L2CAP_CID_DYN_START; |
165 | 167 | ||
166 | for (; cid < L2CAP_CID_DYN_END; cid++) { | 168 | for (; cid < L2CAP_CID_DYN_END; cid++) { |
167 | if(!__l2cap_get_chan_by_scid(l, cid)) | 169 | if (!__l2cap_get_chan_by_scid(l, cid)) |
168 | return cid; | 170 | return cid; |
169 | } | 171 | } |
170 | 172 | ||
@@ -204,7 +206,8 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so | |||
204 | { | 206 | { |
205 | struct l2cap_chan_list *l = &conn->chan_list; | 207 | struct l2cap_chan_list *l = &conn->chan_list; |
206 | 208 | ||
207 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); | 209 | BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, |
210 | l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid); | ||
208 | 211 | ||
209 | conn->disc_reason = 0x13; | 212 | conn->disc_reason = 0x13; |
210 | 213 | ||
@@ -272,7 +275,7 @@ static inline int l2cap_check_security(struct sock *sk) | |||
272 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) | 275 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) |
273 | auth_type = HCI_AT_NO_BONDING_MITM; | 276 | auth_type = HCI_AT_NO_BONDING_MITM; |
274 | else | 277 | else |
275 | auth_type = HCI_AT_NO_BONDING; | 278 | auth_type = HCI_AT_NO_BONDING; |
276 | 279 | ||
277 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) | 280 | if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) |
278 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | 281 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; |
@@ -588,7 +591,8 @@ static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t | |||
588 | struct sock *s; | 591 | struct sock *s; |
589 | read_lock(&l2cap_sk_list.lock); | 592 | read_lock(&l2cap_sk_list.lock); |
590 | s = __l2cap_get_sock_by_psm(state, psm, src); | 593 | s = __l2cap_get_sock_by_psm(state, psm, src); |
591 | if (s) bh_lock_sock(s); | 594 | if (s) |
595 | bh_lock_sock(s); | ||
592 | read_unlock(&l2cap_sk_list.lock); | 596 | read_unlock(&l2cap_sk_list.lock); |
593 | return s; | 597 | return s; |
594 | } | 598 | } |
@@ -849,7 +853,8 @@ static int l2cap_do_connect(struct sock *sk) | |||
849 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), | 853 | BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), |
850 | l2cap_pi(sk)->psm); | 854 | l2cap_pi(sk)->psm); |
851 | 855 | ||
852 | if (!(hdev = hci_get_route(dst, src))) | 856 | hdev = hci_get_route(dst, src); |
857 | if (!hdev) | ||
853 | return -EHOSTUNREACH; | 858 | return -EHOSTUNREACH; |
854 | 859 | ||
855 | hci_dev_lock_bh(hdev); | 860 | hci_dev_lock_bh(hdev); |
@@ -950,7 +955,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
950 | goto done; | 955 | goto done; |
951 | } | 956 | } |
952 | 957 | ||
953 | switch(sk->sk_state) { | 958 | switch (sk->sk_state) { |
954 | case BT_CONNECT: | 959 | case BT_CONNECT: |
955 | case BT_CONNECT2: | 960 | case BT_CONNECT2: |
956 | case BT_CONFIG: | 961 | case BT_CONFIG: |
@@ -975,7 +980,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al | |||
975 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | 980 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); |
976 | l2cap_pi(sk)->psm = la.l2_psm; | 981 | l2cap_pi(sk)->psm = la.l2_psm; |
977 | 982 | ||
978 | if ((err = l2cap_do_connect(sk))) | 983 | err = l2cap_do_connect(sk); |
984 | if (err) | ||
979 | goto done; | 985 | goto done; |
980 | 986 | ||
981 | wait: | 987 | wait: |
@@ -1114,7 +1120,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len) | |||
1114 | { | 1120 | { |
1115 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1121 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
1116 | struct sk_buff *skb, **frag; | 1122 | struct sk_buff *skb, **frag; |
1117 | int err, hlen, count, sent=0; | 1123 | int err, hlen, count, sent = 0; |
1118 | struct l2cap_hdr *lh; | 1124 | struct l2cap_hdr *lh; |
1119 | 1125 | ||
1120 | BT_DBG("sk %p len %d", sk, len); | 1126 | BT_DBG("sk %p len %d", sk, len); |
@@ -1167,8 +1173,8 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len) | |||
1167 | 1173 | ||
1168 | frag = &(*frag)->next; | 1174 | frag = &(*frag)->next; |
1169 | } | 1175 | } |
1170 | 1176 | err = hci_send_acl(conn->hcon, skb, 0); | |
1171 | if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0) | 1177 | if (err < 0) |
1172 | goto fail; | 1178 | goto fail; |
1173 | 1179 | ||
1174 | return sent; | 1180 | return sent; |
@@ -1556,7 +1562,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1556 | { | 1562 | { |
1557 | struct l2cap_chan_list *l = &conn->chan_list; | 1563 | struct l2cap_chan_list *l = &conn->chan_list; |
1558 | struct sk_buff *nskb; | 1564 | struct sk_buff *nskb; |
1559 | struct sock * sk; | 1565 | struct sock *sk; |
1560 | 1566 | ||
1561 | BT_DBG("conn %p", conn); | 1567 | BT_DBG("conn %p", conn); |
1562 | 1568 | ||
@@ -1568,8 +1574,8 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1568 | /* Don't send frame to the socket it came from */ | 1574 | /* Don't send frame to the socket it came from */ |
1569 | if (skb->sk == sk) | 1575 | if (skb->sk == sk) |
1570 | continue; | 1576 | continue; |
1571 | 1577 | nskb = skb_clone(skb, GFP_ATOMIC); | |
1572 | if (!(nskb = skb_clone(skb, GFP_ATOMIC))) | 1578 | if (!nskb) |
1573 | continue; | 1579 | continue; |
1574 | 1580 | ||
1575 | if (sock_queue_rcv_skb(sk, nskb)) | 1581 | if (sock_queue_rcv_skb(sk, nskb)) |
@@ -1587,7 +1593,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | |||
1587 | struct l2cap_hdr *lh; | 1593 | struct l2cap_hdr *lh; |
1588 | int len, count; | 1594 | int len, count; |
1589 | 1595 | ||
1590 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen); | 1596 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", |
1597 | conn, code, ident, dlen); | ||
1591 | 1598 | ||
1592 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; | 1599 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; |
1593 | count = min_t(unsigned int, conn->mtu, len); | 1600 | count = min_t(unsigned int, conn->mtu, len); |
@@ -1966,10 +1973,12 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd | |||
1966 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); | 1973 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status); |
1967 | 1974 | ||
1968 | if (scid) { | 1975 | if (scid) { |
1969 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid))) | 1976 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); |
1977 | if (!sk) | ||
1970 | return 0; | 1978 | return 0; |
1971 | } else { | 1979 | } else { |
1972 | if (!(sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident))) | 1980 | sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident); |
1981 | if (!sk) | ||
1973 | return 0; | 1982 | return 0; |
1974 | } | 1983 | } |
1975 | 1984 | ||
@@ -2012,7 +2021,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2012 | 2021 | ||
2013 | BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); | 2022 | BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags); |
2014 | 2023 | ||
2015 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) | 2024 | sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); |
2025 | if (!sk) | ||
2016 | return -ENOENT; | 2026 | return -ENOENT; |
2017 | 2027 | ||
2018 | if (sk->sk_state == BT_DISCONN) | 2028 | if (sk->sk_state == BT_DISCONN) |
@@ -2079,9 +2089,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2079 | flags = __le16_to_cpu(rsp->flags); | 2089 | flags = __le16_to_cpu(rsp->flags); |
2080 | result = __le16_to_cpu(rsp->result); | 2090 | result = __le16_to_cpu(rsp->result); |
2081 | 2091 | ||
2082 | BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result); | 2092 | BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", |
2093 | scid, flags, result); | ||
2083 | 2094 | ||
2084 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid))) | 2095 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); |
2096 | if (!sk) | ||
2085 | return 0; | 2097 | return 0; |
2086 | 2098 | ||
2087 | switch (result) { | 2099 | switch (result) { |
@@ -2142,7 +2154,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd | |||
2142 | 2154 | ||
2143 | BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); | 2155 | BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid); |
2144 | 2156 | ||
2145 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid))) | 2157 | sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid); |
2158 | if (!sk) | ||
2146 | return 0; | 2159 | return 0; |
2147 | 2160 | ||
2148 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2161 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
@@ -2169,7 +2182,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd | |||
2169 | 2182 | ||
2170 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); | 2183 | BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid); |
2171 | 2184 | ||
2172 | if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid))) | 2185 | sk = l2cap_get_chan_by_scid(&conn->chan_list, scid); |
2186 | if (!sk) | ||
2173 | return 0; | 2187 | return 0; |
2174 | 2188 | ||
2175 | l2cap_chan_del(sk, 0); | 2189 | l2cap_chan_del(sk, 0); |
@@ -2403,7 +2417,8 @@ drop: | |||
2403 | kfree_skb(skb); | 2417 | kfree_skb(skb); |
2404 | 2418 | ||
2405 | done: | 2419 | done: |
2406 | if (sk) bh_unlock_sock(sk); | 2420 | if (sk) |
2421 | bh_unlock_sock(sk); | ||
2407 | return 0; | 2422 | return 0; |
2408 | } | 2423 | } |
2409 | 2424 | ||
@@ -2650,7 +2665,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
2650 | } | 2665 | } |
2651 | 2666 | ||
2652 | /* Allocate skb for the complete frame (with header) */ | 2667 | /* Allocate skb for the complete frame (with header) */ |
2653 | if (!(conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC))) | 2668 | conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC); |
2669 | if (!conn->rx_skb) | ||
2654 | goto drop; | 2670 | goto drop; |
2655 | 2671 | ||
2656 | skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), | 2672 | skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len), |
@@ -2710,7 +2726,7 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf) | |||
2710 | 2726 | ||
2711 | read_unlock_bh(&l2cap_sk_list.lock); | 2727 | read_unlock_bh(&l2cap_sk_list.lock); |
2712 | 2728 | ||
2713 | return (str - buf); | 2729 | return str - buf; |
2714 | } | 2730 | } |
2715 | 2731 | ||
2716 | static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); | 2732 | static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL); |