diff options
-rw-r--r-- | net/bluetooth/l2cap.c | 172 |
1 files changed, 108 insertions, 64 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 4fcf24af7590..c1239852834a 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -76,11 +76,21 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | |||
76 | static void l2cap_sock_timeout(unsigned long arg) | 76 | static void l2cap_sock_timeout(unsigned long arg) |
77 | { | 77 | { |
78 | struct sock *sk = (struct sock *) arg; | 78 | struct sock *sk = (struct sock *) arg; |
79 | int reason; | ||
79 | 80 | ||
80 | BT_DBG("sock %p state %d", sk, sk->sk_state); | 81 | BT_DBG("sock %p state %d", sk, sk->sk_state); |
81 | 82 | ||
82 | bh_lock_sock(sk); | 83 | bh_lock_sock(sk); |
83 | __l2cap_sock_close(sk, ETIMEDOUT); | 84 | |
85 | if (sk->sk_state == BT_CONNECT && | ||
86 | (l2cap_pi(sk)->link_mode & (L2CAP_LM_AUTH | | ||
87 | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE))) | ||
88 | reason = ECONNREFUSED; | ||
89 | else | ||
90 | reason = ETIMEDOUT; | ||
91 | |||
92 | __l2cap_sock_close(sk, reason); | ||
93 | |||
84 | bh_unlock_sock(sk); | 94 | bh_unlock_sock(sk); |
85 | 95 | ||
86 | l2cap_sock_kill(sk); | 96 | l2cap_sock_kill(sk); |
@@ -240,7 +250,7 @@ static void l2cap_chan_del(struct sock *sk, int err) | |||
240 | hci_conn_put(conn->hcon); | 250 | hci_conn_put(conn->hcon); |
241 | } | 251 | } |
242 | 252 | ||
243 | sk->sk_state = BT_CLOSED; | 253 | sk->sk_state = BT_CLOSED; |
244 | sock_set_flag(sk, SOCK_ZAPPED); | 254 | sock_set_flag(sk, SOCK_ZAPPED); |
245 | 255 | ||
246 | if (err) | 256 | if (err) |
@@ -307,14 +317,16 @@ static void l2cap_do_start(struct sock *sk) | |||
307 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 317 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
308 | 318 | ||
309 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 319 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { |
310 | struct l2cap_conn_req req; | 320 | if (l2cap_check_link_mode(sk)) { |
311 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 321 | struct l2cap_conn_req req; |
312 | req.psm = l2cap_pi(sk)->psm; | 322 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
323 | req.psm = l2cap_pi(sk)->psm; | ||
313 | 324 | ||
314 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | 325 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); |
315 | 326 | ||
316 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 327 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
317 | L2CAP_CONN_REQ, sizeof(req), &req); | 328 | L2CAP_CONN_REQ, sizeof(req), &req); |
329 | } | ||
318 | } else { | 330 | } else { |
319 | struct l2cap_info_req req; | 331 | struct l2cap_info_req req; |
320 | req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); | 332 | req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); |
@@ -349,14 +361,16 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
349 | } | 361 | } |
350 | 362 | ||
351 | if (sk->sk_state == BT_CONNECT) { | 363 | if (sk->sk_state == BT_CONNECT) { |
352 | struct l2cap_conn_req req; | 364 | if (l2cap_check_link_mode(sk)) { |
353 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 365 | struct l2cap_conn_req req; |
354 | req.psm = l2cap_pi(sk)->psm; | 366 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
367 | req.psm = l2cap_pi(sk)->psm; | ||
355 | 368 | ||
356 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | 369 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); |
357 | 370 | ||
358 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 371 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
359 | L2CAP_CONN_REQ, sizeof(req), &req); | 372 | L2CAP_CONN_REQ, sizeof(req), &req); |
373 | } | ||
360 | } else if (sk->sk_state == BT_CONNECT2) { | 374 | } else if (sk->sk_state == BT_CONNECT2) { |
361 | struct l2cap_conn_rsp rsp; | 375 | struct l2cap_conn_rsp rsp; |
362 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 376 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
@@ -455,7 +469,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
455 | 469 | ||
456 | conn->feat_mask = 0; | 470 | conn->feat_mask = 0; |
457 | 471 | ||
458 | setup_timer(&conn->info_timer, l2cap_info_timeout, (unsigned long)conn); | 472 | setup_timer(&conn->info_timer, l2cap_info_timeout, |
473 | (unsigned long) conn); | ||
459 | 474 | ||
460 | spin_lock_init(&conn->lock); | 475 | spin_lock_init(&conn->lock); |
461 | rwlock_init(&conn->chan_list.lock); | 476 | rwlock_init(&conn->chan_list.lock); |
@@ -567,7 +582,7 @@ static void l2cap_sock_cleanup_listen(struct sock *parent) | |||
567 | while ((sk = bt_accept_dequeue(parent, NULL))) | 582 | while ((sk = bt_accept_dequeue(parent, NULL))) |
568 | l2cap_sock_close(sk); | 583 | l2cap_sock_close(sk); |
569 | 584 | ||
570 | parent->sk_state = BT_CLOSED; | 585 | parent->sk_state = BT_CLOSED; |
571 | sock_set_flag(parent, SOCK_ZAPPED); | 586 | sock_set_flag(parent, SOCK_ZAPPED); |
572 | } | 587 | } |
573 | 588 | ||
@@ -610,9 +625,8 @@ static void __l2cap_sock_close(struct sock *sk, int reason) | |||
610 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | 625 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
611 | l2cap_send_cmd(conn, l2cap_get_ident(conn), | 626 | l2cap_send_cmd(conn, l2cap_get_ident(conn), |
612 | L2CAP_DISCONN_REQ, sizeof(req), &req); | 627 | L2CAP_DISCONN_REQ, sizeof(req), &req); |
613 | } else { | 628 | } else |
614 | l2cap_chan_del(sk, reason); | 629 | l2cap_chan_del(sk, reason); |
615 | } | ||
616 | break; | 630 | break; |
617 | 631 | ||
618 | case BT_CONNECT: | 632 | case BT_CONNECT: |
@@ -681,9 +695,9 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
681 | sock_reset_flag(sk, SOCK_ZAPPED); | 695 | sock_reset_flag(sk, SOCK_ZAPPED); |
682 | 696 | ||
683 | sk->sk_protocol = proto; | 697 | sk->sk_protocol = proto; |
684 | sk->sk_state = BT_OPEN; | 698 | sk->sk_state = BT_OPEN; |
685 | 699 | ||
686 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long)sk); | 700 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); |
687 | 701 | ||
688 | bt_sock_link(&l2cap_sk_list, sk); | 702 | bt_sock_link(&l2cap_sk_list, sk); |
689 | return sk; | 703 | return sk; |
@@ -1201,7 +1215,8 @@ static int l2cap_sock_shutdown(struct socket *sock, int how) | |||
1201 | __l2cap_sock_close(sk, 0); | 1215 | __l2cap_sock_close(sk, 0); |
1202 | 1216 | ||
1203 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | 1217 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) |
1204 | err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); | 1218 | err = bt_sock_wait_state(sk, BT_CLOSED, |
1219 | sk->sk_lingertime); | ||
1205 | } | 1220 | } |
1206 | release_sock(sk); | 1221 | release_sock(sk); |
1207 | return err; | 1222 | return err; |
@@ -1245,6 +1260,11 @@ static void l2cap_chan_ready(struct sock *sk) | |||
1245 | */ | 1260 | */ |
1246 | parent->sk_data_ready(parent, 0); | 1261 | parent->sk_data_ready(parent, 0); |
1247 | } | 1262 | } |
1263 | |||
1264 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) { | ||
1265 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
1266 | hci_conn_change_link_key(conn->hcon); | ||
1267 | } | ||
1248 | } | 1268 | } |
1249 | 1269 | ||
1250 | /* Copy frame to all raw sockets on that connection */ | 1270 | /* Copy frame to all raw sockets on that connection */ |
@@ -1778,7 +1798,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
1778 | 1798 | ||
1779 | default: | 1799 | default: |
1780 | sk->sk_state = BT_DISCONN; | 1800 | sk->sk_state = BT_DISCONN; |
1781 | sk->sk_err = ECONNRESET; | 1801 | sk->sk_err = ECONNRESET; |
1782 | l2cap_sock_set_timer(sk, HZ * 5); | 1802 | l2cap_sock_set_timer(sk, HZ * 5); |
1783 | { | 1803 | { |
1784 | struct l2cap_disconn_req req; | 1804 | struct l2cap_disconn_req req; |
@@ -2151,9 +2171,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | |||
2151 | { | 2171 | { |
2152 | struct l2cap_chan_list *l; | 2172 | struct l2cap_chan_list *l; |
2153 | struct l2cap_conn *conn = hcon->l2cap_data; | 2173 | struct l2cap_conn *conn = hcon->l2cap_data; |
2154 | struct l2cap_conn_rsp rsp; | ||
2155 | struct sock *sk; | 2174 | struct sock *sk; |
2156 | int result; | ||
2157 | 2175 | ||
2158 | if (!conn) | 2176 | if (!conn) |
2159 | return 0; | 2177 | return 0; |
@@ -2169,37 +2187,53 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | |||
2169 | 2187 | ||
2170 | bh_lock_sock(sk); | 2188 | bh_lock_sock(sk); |
2171 | 2189 | ||
2172 | if (sk->sk_state != BT_CONNECT2) { | ||
2173 | bh_unlock_sock(sk); | ||
2174 | continue; | ||
2175 | } | ||
2176 | |||
2177 | if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && | 2190 | if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && |
2178 | !(hcon->link_mode & HCI_LM_ENCRYPT)) { | 2191 | !(hcon->link_mode & HCI_LM_ENCRYPT) && |
2192 | !status) { | ||
2179 | bh_unlock_sock(sk); | 2193 | bh_unlock_sock(sk); |
2180 | continue; | 2194 | continue; |
2181 | } | 2195 | } |
2182 | 2196 | ||
2183 | if (!status) { | 2197 | if (sk->sk_state == BT_CONNECT) { |
2184 | sk->sk_state = BT_CONFIG; | 2198 | if (!status) { |
2185 | result = 0; | 2199 | struct l2cap_conn_req req; |
2186 | } else { | 2200 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
2187 | sk->sk_state = BT_DISCONN; | 2201 | req.psm = l2cap_pi(sk)->psm; |
2188 | l2cap_sock_set_timer(sk, HZ/10); | 2202 | |
2189 | result = L2CAP_CR_SEC_BLOCK; | 2203 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); |
2190 | } | 2204 | |
2205 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
2206 | L2CAP_CONN_REQ, sizeof(req), &req); | ||
2207 | } else { | ||
2208 | l2cap_sock_clear_timer(sk); | ||
2209 | l2cap_sock_set_timer(sk, HZ / 10); | ||
2210 | } | ||
2211 | } else if (sk->sk_state == BT_CONNECT2) { | ||
2212 | struct l2cap_conn_rsp rsp; | ||
2213 | __u16 result; | ||
2214 | |||
2215 | if (!status) { | ||
2216 | sk->sk_state = BT_CONFIG; | ||
2217 | result = L2CAP_CR_SUCCESS; | ||
2218 | } else { | ||
2219 | sk->sk_state = BT_DISCONN; | ||
2220 | l2cap_sock_set_timer(sk, HZ / 10); | ||
2221 | result = L2CAP_CR_SEC_BLOCK; | ||
2222 | } | ||
2191 | 2223 | ||
2192 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 2224 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); |
2193 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2225 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); |
2194 | rsp.result = cpu_to_le16(result); | 2226 | rsp.result = cpu_to_le16(result); |
2195 | rsp.status = cpu_to_le16(0); | 2227 | rsp.status = cpu_to_le16(0); |
2196 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 2228 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
2197 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 2229 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); |
2230 | } | ||
2198 | 2231 | ||
2199 | bh_unlock_sock(sk); | 2232 | bh_unlock_sock(sk); |
2200 | } | 2233 | } |
2201 | 2234 | ||
2202 | read_unlock(&l->lock); | 2235 | read_unlock(&l->lock); |
2236 | |||
2203 | return 0; | 2237 | return 0; |
2204 | } | 2238 | } |
2205 | 2239 | ||
@@ -2207,9 +2241,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
2207 | { | 2241 | { |
2208 | struct l2cap_chan_list *l; | 2242 | struct l2cap_chan_list *l; |
2209 | struct l2cap_conn *conn = hcon->l2cap_data; | 2243 | struct l2cap_conn *conn = hcon->l2cap_data; |
2210 | struct l2cap_conn_rsp rsp; | ||
2211 | struct sock *sk; | 2244 | struct sock *sk; |
2212 | int result; | ||
2213 | 2245 | ||
2214 | if (!conn) | 2246 | if (!conn) |
2215 | return 0; | 2247 | return 0; |
@@ -2234,34 +2266,46 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
2234 | continue; | 2266 | continue; |
2235 | } | 2267 | } |
2236 | 2268 | ||
2237 | if (sk->sk_state != BT_CONNECT2) { | 2269 | if (sk->sk_state == BT_CONNECT) { |
2238 | bh_unlock_sock(sk); | 2270 | if (!status) { |
2239 | continue; | 2271 | struct l2cap_conn_req req; |
2240 | } | 2272 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); |
2273 | req.psm = l2cap_pi(sk)->psm; | ||
2241 | 2274 | ||
2242 | if (!status) { | 2275 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); |
2243 | sk->sk_state = BT_CONFIG; | ||
2244 | result = 0; | ||
2245 | } else { | ||
2246 | sk->sk_state = BT_DISCONN; | ||
2247 | l2cap_sock_set_timer(sk, HZ/10); | ||
2248 | result = L2CAP_CR_SEC_BLOCK; | ||
2249 | } | ||
2250 | 2276 | ||
2251 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | 2277 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, |
2252 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | 2278 | L2CAP_CONN_REQ, sizeof(req), &req); |
2253 | rsp.result = cpu_to_le16(result); | 2279 | } else { |
2254 | rsp.status = cpu_to_le16(0); | 2280 | l2cap_sock_clear_timer(sk); |
2255 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | 2281 | l2cap_sock_set_timer(sk, HZ / 10); |
2256 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | 2282 | } |
2283 | } else if (sk->sk_state == BT_CONNECT2) { | ||
2284 | struct l2cap_conn_rsp rsp; | ||
2285 | __u16 result; | ||
2257 | 2286 | ||
2258 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | 2287 | if (!status) { |
2259 | hci_conn_change_link_key(hcon); | 2288 | sk->sk_state = BT_CONFIG; |
2289 | result = L2CAP_CR_SUCCESS; | ||
2290 | } else { | ||
2291 | sk->sk_state = BT_DISCONN; | ||
2292 | l2cap_sock_set_timer(sk, HZ / 10); | ||
2293 | result = L2CAP_CR_SEC_BLOCK; | ||
2294 | } | ||
2295 | |||
2296 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
2297 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
2298 | rsp.result = cpu_to_le16(result); | ||
2299 | rsp.status = cpu_to_le16(0); | ||
2300 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
2301 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
2302 | } | ||
2260 | 2303 | ||
2261 | bh_unlock_sock(sk); | 2304 | bh_unlock_sock(sk); |
2262 | } | 2305 | } |
2263 | 2306 | ||
2264 | read_unlock(&l->lock); | 2307 | read_unlock(&l->lock); |
2308 | |||
2265 | return 0; | 2309 | return 0; |
2266 | } | 2310 | } |
2267 | 2311 | ||