From 75e34f5cf69bd731d3b7375a786d4a15494fb8c6 Mon Sep 17 00:00:00 2001 From: Kuba Pawlak Date: Mon, 5 Oct 2015 18:44:15 +0200 Subject: Bluetooth: Fix crash on SCO disconnect When disconnecting audio from the phone's side, it may happen, that a thread handling HCI message 'disconnection complete' will get preempted in 'sco_conn_del' before calling 'sco_sock_kill', still holding a pointer to struct sock sk. Interrupting thread started in 'sco_sock_shutdown' will carry on releasing resources and will eventually release struct sock. When execution goes back to first thread it will call sco_sock_kill using now invalid pointer to already destroyed socket. Fix is to grab a reference to the socket a release it after calling 'sco_sock_kill'. [ 166.358213] BUG: unable to handle kernel paging request at 7541203a [ 166.365228] IP: [] bt_sock_unlink+0x1a/0x38 [bluetooth] [ 166.372068] *pdpt = 0000000024b19001 *pde = 0000000000000000 [ 166.378483] Oops: 0002 [#1] PREEMPT SMP [ 166.382871] Modules linked in: evdev ecb rfcomm(O) libcomposite usb2380 udc_core bnep(O) btusb(O) btbcm(O) btintel(O) cdc_acm bluetooth(O) arc4 uinput hid_multitouch iwlmvm(O) usbhid hide [ 166.424233] Pid: 338, comm: kworker/u:2H Tainted: G O 3.8.0-115.1-plk-adaptation-byt-ivi-brd #1 [ 166.435112] EIP: 0060:[] EFLAGS: 00010206 CPU: 0 [ 166.441259] EIP is at bt_sock_unlink+0x1a/0x38 [bluetooth] [ 166.447382] EAX: 632e6563 EBX: e4bfc600 ECX: e466d4d3 EDX: 7541203a [ 166.454369] ESI: fb7278ac EDI: e4d52000 EBP: e4669e20 ESP: e4669e0c [ 166.461366] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 [ 166.467391] CR0: 8005003b CR2: 7541203a CR3: 24aba000 CR4: 001007f0 [ 166.474387] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [ 166.481375] DR6: ffff0ff0 DR7: 00000400 [ 166.485654] Process kworker/u:2H (pid: 338, ti=e4668000 task=e466e030 task.ti=e4668000) [ 166.494591] Stack: [ 166.496830] e4bfc600 e4bfc600 fb715c28 e4717ee0 e4d52000 e4669e3c fb715cf3 e4bfc634 [ 166.505518] 00000068 e4d52000 e4c32000 fb7277c0 e4669e6c fb6f2019 0000004a 00000216 [ 166.514205] e4660101 e4c32008 02000001 00000013 e4d52000 e4c32000 e3dc9240 00000005 [ 166.522891] Call Trace: [ 166.525654] [] ? sco_sock_kill+0x73/0x9a [bluetooth] [ 166.532295] [] ? sco_conn_del+0xa4/0xbf [bluetooth] [ 166.538836] [] ? hci_disconn_complete_evt.clone.55+0x1bd/0x205 [bluetooth] [ 166.547609] [] ? hci_event_packet+0x297/0x223c [bluetooth] [ 166.554805] [] ? dequeue_task+0xaf/0xb7 [ 166.560154] [] ? finish_task_switch+0x50/0x89 [ 166.566086] [] ? __schedule+0x638/0x6b8 [ 166.571460] [] ? hci_rx_work+0xb9/0x2b8 [bluetooth] [ 166.577975] [] ? process_one_work+0x157/0x21b [ 166.583933] [] ? hci_cmd_work+0xef/0xef [bluetooth] [ 166.590448] [] ? worker_thread+0x16e/0x20a [ 166.596088] [] ? manage_workers+0x1cf/0x1cf [ 166.601826] [] ? kthread+0x8d/0x92 [ 166.606691] [] ? ret_from_kernel_thread+0x1b/0x28 [ 166.613010] [] ? __init_kthread_worker+0x24/0x24 [ 166.619230] Code: 85 63 ff ff ff 31 db 8d 65 f4 89 d8 5b 5e 5f 5d c3 56 8d 70 04 53 89 f0 89 d3 e8 7e 17 c6 c5 8b 53 28 85 d2 74 1a 8b 43 24 85 c0 <89> 02 74 03 89 50 04 c7 43 28 00 00 00 [ 166.640501] EIP: [] bt_sock_unlink+0x1a/0x38 [bluetooth] SS:ESP 0068:e4669e0c [ 166.649474] CR2: 000000007541203a [ 166.653420] ---[ end trace 0181ff2c9e42d51e ]--- [ 166.658609] note: kworker/u:2H[338] exited with preempt_count 1 Signed-off-by: Kuba Pawlak Signed-off-by: Marcel Holtmann --- net/bluetooth/sco.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index f315c8d0e43b..e21c53b08da4 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -170,11 +170,13 @@ static void sco_conn_del(struct hci_conn *hcon, int err) sco_conn_unlock(conn); if (sk) { + sock_hold(sk); bh_lock_sock(sk); sco_sock_clear_timer(sk); sco_chan_del(sk, err); bh_unlock_sock(sk); sco_sock_kill(sk); + sock_put(sk); } hcon->sco_data = NULL; -- cgit v1.2.3-59-g8ed1b From 435c513369768f5840cd57101e398bc450fd26de Mon Sep 17 00:00:00 2001 From: Kuba Pawlak Date: Mon, 5 Oct 2015 18:44:16 +0200 Subject: Bluetooth: Fix locking issue on SCO disconnection Thread handling SCO disconnection may get preempted in '__sco_sock_close' after dropping a reference to hci_conn but before marking this as NULL in associated struct sco_conn. When execution returs to this thread, this connection will possibly be released, resulting in kernel crash Lock connection before this point. BUG: unable to handle kernel NULL pointer dereference at (null) IP: [] __sco_sock_close+0x194/0x1ff [bluetooth] *pdpt = 0000000023da6001 *pde = 0000000000000000 Oops: 0002 [#1] PREEMPT SMP Modules linked in: evdev ecb rfcomm(O) libcomposite usb2380 udc_core bnep(O) btusb(O) btbcm(O) cdc_acm btintel(O) bluetooth(O) arc4 uinput hid_multitouch usbhid iwlmvm(O) hide Pid: 984, comm: bluetooth Tainted: G O 3.8.0-115.1-plk-adaptation-byt-ivi-brd #1 EIP: 0060:[] EFLAGS: 00010282 CPU: 2 EIP is at __sco_sock_close+0x194/0x1ff [bluetooth] EAX: 00000000 EBX: e49d7600 ECX: ef1ec3c2 EDX: 000000c3 ESI: e4c12000 EDI: 00000000 EBP: ef1edf5c ESP: ef1edf4c DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 CR0: 80050033 CR2: 00000000 CR3: 23da7000 CR4: 001007f0 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Process bluetooth (pid: 984, ti=ef1ec000 task=e47f2550 task.ti=ef1ec000) Stack: e4c120d0 e49d7600 00000000 08421a40 ef1edf70 fb770b7a 00000002 e8a4cc80 08421a40 ef1ec000 c12966b1 00000001 00000000 0000000b 084954c8 c1296b6c 0000001b 00000002 0000001b 00000002 00000000 00000002 b2524880 00000046 Call Trace: [] ? sco_sock_shutdown+0x56/0x95 [bluetooth] [] ? sys_shutdown+0x37/0x53 [] ? sys_socketcall+0x12e/0x1be [] ? sysenter_do_call+0x12/0x26 [] ? ip_vs_control_net_cleanup+0x46/0xb1 Code: e8 90 6b 8c c5 f6 05 72 5d 78 fb 04 74 17 8b 46 08 50 56 68 0a fd 77 fb 68 60 5d 78 fb e8 68 95 9e c5 83 c4 10 8b 83 fc 01 00 00 00 00 00 00 00 eb 32 ba 68 00 00 0b EIP: [] __sco_sock_close+0x194/0x1ff [bluetooth] SS:ESP 0068:ef1edf4c CR2: 0000000000000000 ---[ end trace 47fa2f55a9544e69 ]--- Signed-off-by: Kuba Pawlak Signed-off-by: Marcel Holtmann --- net/bluetooth/sco.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'net') diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index e21c53b08da4..09051e4cbade 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -416,8 +416,10 @@ static void __sco_sock_close(struct sock *sk) if (sco_pi(sk)->conn->hcon) { sk->sk_state = BT_DISCONN; sco_sock_set_timer(sk, SCO_DISCONN_TIMEOUT); + sco_conn_lock(sco_pi(sk)->conn); hci_conn_drop(sco_pi(sk)->conn->hcon); sco_pi(sk)->conn->hcon = NULL; + sco_conn_unlock(sco_pi(sk)->conn); } else sco_chan_del(sk, ECONNRESET); break; -- cgit v1.2.3-59-g8ed1b From 1da5537eccd865b83fedbbb7ea704669f6d255fd Mon Sep 17 00:00:00 2001 From: Kuba Pawlak Date: Mon, 5 Oct 2015 18:44:17 +0200 Subject: Bluetooth: Fix locking issue during fast SCO reconnection. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When SCO connection is requested and disconnected fast, there is a change that sco_sock_shutdown is going to preempt thread started in sco_connect_cfm. When this happens struct sock sk may be removed but a pointer to it is still held in sco_conn_ready, where embedded spinlock is used. If it is used, but struct sock has been removed, it will crash. Block connection object, which will prevent struct sock from being removed and give connection process chance to finish. BUG: spinlock bad magic on CPU#0, kworker/u:2H/319 lock: 0xe3e99434, .magic: f3000000, .owner: (���/0, .owner_cpu: -203804160 Pid: 319, comm: kworker/u:2H Tainted: G O 3.8.0-115.1-plk-adaptation-byt-ivi-brd #1 Call Trace: [] ? do_raw_spin_lock+0x19/0xe9 [] ? sco_connect_cfm+0x92/0x236 [bluetooth] [] ? hci_sync_conn_complete_evt.clone.101+0x18b/0x1cb [bluetooth] [] ? hci_event_packet+0x1acd/0x21a6 [bluetooth] [] ? finish_task_switch+0x50/0x89 [] ? __schedule+0x638/0x6b8 [] ? hci_rx_work+0xb9/0x2b8 [bluetooth] [] ? queue_delayed_work_on+0x21/0x2a [] ? process_one_work+0x157/0x21b [] ? hci_cmd_work+0xef/0xef [bluetooth] [] ? worker_thread+0x16e/0x20a [] ? manage_workers+0x1cf/0x1cf [] ? kthread+0x8d/0x92 [] ? ret_from_kernel_thread+0x1b/0x28 [] ? __init_kthread_worker+0x24/0x24 BUG: unable to handle kernel NULL pointer dereference at (null) IP: [< (null)>] (null) *pdpt = 00000000244e1001 *pde = 0000000000000000 Oops: 0010 [#1] PREEMPT SMP Modules linked in: evdev ecb rfcomm(O) libcomposite usb2380 udc_core bnep(O) btusb(O) btbcm(O) cdc_acm btintel(O) bluetooth(O) arc4 uinput hid_multitouch usbhid hid iwlmvm(O)e Pid: 319, comm: kworker/u:2H Tainted: G O 3.8.0-115.1-plk-adaptation-byt-ivi-brd #1 EIP: 0060:[<00000000>] EFLAGS: 00010246 CPU: 0 EIP is at 0x0 EAX: e3e99400 EBX: e3e99400 ECX: 00000100 EDX: 00000000 ESI: e3e99434 EDI: fb763ce0 EBP: e49b9e44 ESP: e49b9e14 DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 CR0: 8005003b CR2: 00000000 CR3: 24444000 CR4: 001007f0 DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 DR6: ffff0ff0 DR7: 00000400 Process kworker/u:2H (pid: 319, ti=e49b8000 task=e4ab9030 task.ti=e49b8000) Stack: fb75355b 00000246 fb763900 22222222 22222222 22222222 e3f94460 e3ca7c0a e49b9e4c e3f34c00 e3ca7c0a fb763ce0 e49b9e6c fb731dbc 02000246 e4cec85c e4cec008 00000000 e3f34c00 e4cec000 e3c2ce00 0000002c e49b9ed0 fb734ee7 Call Trace: [] ? sco_connect_cfm+0x9e/0x236 [bluetooth] [] ? hci_sync_conn_complete_evt.clone.101+0x18b/0x1cb [bluetooth] [] ? hci_event_packet+0x1acd/0x21a6 [bluetooth] [] ? finish_task_switch+0x50/0x89 [] ? __schedule+0x638/0x6b8 [] ? hci_rx_work+0xb9/0x2b8 [bluetooth] [] ? queue_delayed_work_on+0x21/0x2a [] ? process_one_work+0x157/0x21b [] ? hci_cmd_work+0xef/0xef [bluetooth] [] ? worker_thread+0x16e/0x20a [] ? manage_workers+0x1cf/0x1cf [] ? kthread+0x8d/0x92 [] ? ret_from_kernel_thread+0x1b/0x28 [] ? __init_kthread_worker+0x24/0x24 Code: Bad EIP value. EIP: [<00000000>] 0x0 SS:ESP 0068:e49b9e14 CR2: 0000000000000000 ---[ end trace 942a6577c0abd725 ]--- Signed-off-by: Kuba Pawlak Signed-off-by: Marcel Holtmann --- net/bluetooth/sco.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 09051e4cbade..75f843d5423a 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -965,7 +965,9 @@ static int sco_sock_shutdown(struct socket *sock, int how) if (!sk) return 0; + sock_hold(sk); lock_sock(sk); + if (!sk->sk_shutdown) { sk->sk_shutdown = SHUTDOWN_MASK; sco_sock_clear_timer(sk); @@ -976,7 +978,10 @@ static int sco_sock_shutdown(struct socket *sock, int how) err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); } + release_sock(sk); + sock_put(sk); + return err; } -- cgit v1.2.3-59-g8ed1b From d94a61040d8f99cbaf7f3e7686315edcc6dc2400 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Oct 2015 22:45:18 +0100 Subject: Bluetooth: Remove unneeded parenthesis around MSG_OOB There are two checks that are still using (MSG_OOB) instead of just MSG_OOB and so lets just fix them. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/af_bluetooth.c | 2 +- net/bluetooth/hci_sock.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'net') diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index c55717929213..a3bffd1ec2b4 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c @@ -221,7 +221,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, BT_DBG("sock %p sk %p len %zu", sock, sk, len); - if (flags & (MSG_OOB)) + if (flags & MSG_OOB) return -EOPNOTSUPP; skb = skb_recv_datagram(sk, flags, noblock, &err); diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index b9327e8c2d34..c8812a46d831 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -1001,7 +1001,7 @@ static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, BT_DBG("sock %p, sk %p", sock, sk); - if (flags & (MSG_OOB)) + if (flags & MSG_OOB) return -EOPNOTSUPP; if (sk->sk_state == BT_CLOSED) -- cgit v1.2.3-59-g8ed1b From 242c0ebd3730334c43b9c04eeec40d8dd5c3a26e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Oct 2015 22:45:53 +0100 Subject: Bluetooth: Rename bt_cb()->req into bt_cb()->hci The SKB context buffer for HCI request is really not just for requests, information in their are preserved for the whole HCI layer. So it makes more sense to actually rename it into bt_cb()->hci and also call it then struct hci_ctrl. In addition that allows moving the decoded opcode for outgoing packets into that struct. So far it was just consuming valuable space from the main shared items. And opcode are not valid for L2CAP packets. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- include/net/bluetooth/bluetooth.h | 14 +++++++------- net/bluetooth/hci_core.c | 18 +++++++++--------- net/bluetooth/hci_event.c | 4 ++-- net/bluetooth/hci_request.c | 10 +++++----- net/bluetooth/hci_sock.c | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) (limited to 'net') diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index c4defef319d5..42844d7b154a 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -296,22 +296,22 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, u16 opcode, struct sk_buff *skb); -struct req_ctrl { - bool start; - u8 event; - hci_req_complete_t complete; - hci_req_complete_skb_t complete_skb; +struct hci_ctrl { + __u16 opcode; + bool req_start; + u8 req_event; + hci_req_complete_t req_complete; + hci_req_complete_skb_t req_complete_skb; }; struct bt_skb_cb { __u8 pkt_type; __u8 force_active; - __u16 opcode; __u16 expect; __u8 incoming:1; union { struct l2cap_ctrl l2cap; - struct req_ctrl req; + struct hci_ctrl hci; }; }; #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 086ed9389da1..3604e0194f87 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3650,7 +3650,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, /* Stand-alone HCI commands must be flagged as * single-command requests. */ - bt_cb(skb)->req.start = true; + bt_cb(skb)->hci.req_start = true; skb_queue_tail(&hdev->cmd_q, skb); queue_work(hdev->workqueue, &hdev->cmd_work); @@ -4347,7 +4347,7 @@ static bool hci_req_is_complete(struct hci_dev *hdev) if (!skb) return true; - return bt_cb(skb)->req.start; + return bt_cb(skb)->hci.req_start; } static void hci_resend_last(struct hci_dev *hdev) @@ -4407,26 +4407,26 @@ void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status, * callback would be found in hdev->sent_cmd instead of the * command queue (hdev->cmd_q). */ - if (bt_cb(hdev->sent_cmd)->req.complete) { - *req_complete = bt_cb(hdev->sent_cmd)->req.complete; + if (bt_cb(hdev->sent_cmd)->hci.req_complete) { + *req_complete = bt_cb(hdev->sent_cmd)->hci.req_complete; return; } - if (bt_cb(hdev->sent_cmd)->req.complete_skb) { - *req_complete_skb = bt_cb(hdev->sent_cmd)->req.complete_skb; + if (bt_cb(hdev->sent_cmd)->hci.req_complete_skb) { + *req_complete_skb = bt_cb(hdev->sent_cmd)->hci.req_complete_skb; return; } /* Remove all pending commands belonging to this request */ spin_lock_irqsave(&hdev->cmd_q.lock, flags); while ((skb = __skb_dequeue(&hdev->cmd_q))) { - if (bt_cb(skb)->req.start) { + if (bt_cb(skb)->hci.req_start) { __skb_queue_head(&hdev->cmd_q, skb); break; } - *req_complete = bt_cb(skb)->req.complete; - *req_complete_skb = bt_cb(skb)->req.complete_skb; + *req_complete = bt_cb(skb)->hci.req_complete; + *req_complete_skb = bt_cb(skb)->hci.req_complete_skb; kfree_skb(skb); } spin_unlock_irqrestore(&hdev->cmd_q.lock, flags); diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 504892cfb25a..d57c11c1c6b5 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3138,7 +3138,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb, * complete event). */ if (ev->status || - (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event)) + (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->hci.req_event)) hci_req_cmd_complete(hdev, *opcode, ev->status, req_complete, req_complete_skb); @@ -5209,7 +5209,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) u8 status = 0, event = hdr->evt, req_evt = 0; u16 opcode = HCI_OP_NOP; - if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) { + if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->hci.req_event == event) { struct hci_command_hdr *cmd_hdr = (void *) hdev->sent_cmd->data; opcode = __le16_to_cpu(cmd_hdr->opcode); hci_req_cmd_complete(hdev, opcode, status, &req_complete, diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c index 739f966e5d67..981f8a202c27 100644 --- a/net/bluetooth/hci_request.c +++ b/net/bluetooth/hci_request.c @@ -56,8 +56,8 @@ static int req_run(struct hci_request *req, hci_req_complete_t complete, return -ENODATA; skb = skb_peek_tail(&req->cmd_q); - bt_cb(skb)->req.complete = complete; - bt_cb(skb)->req.complete_skb = complete_skb; + bt_cb(skb)->hci.req_complete = complete; + bt_cb(skb)->hci.req_complete_skb = complete_skb; spin_lock_irqsave(&hdev->cmd_q.lock, flags); skb_queue_splice_tail(&req->cmd_q, &hdev->cmd_q); @@ -99,7 +99,7 @@ struct sk_buff *hci_prepare_cmd(struct hci_dev *hdev, u16 opcode, u32 plen, BT_DBG("skb len %d", skb->len); bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; - bt_cb(skb)->opcode = opcode; + bt_cb(skb)->hci.opcode = opcode; return skb; } @@ -128,9 +128,9 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, } if (skb_queue_empty(&req->cmd_q)) - bt_cb(skb)->req.start = true; + bt_cb(skb)->hci.req_start = true; - bt_cb(skb)->req.event = event; + bt_cb(skb)->hci.req_event = event; skb_queue_tail(&req->cmd_q, skb); } diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index c8812a46d831..b1eb8c09a660 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -1249,7 +1249,7 @@ static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, /* Stand-alone HCI commands must be flagged as * single-command requests. */ - bt_cb(skb)->req.start = true; + bt_cb(skb)->hci.req_start = true; skb_queue_tail(&hdev->cmd_q, skb); queue_work(hdev->workqueue, &hdev->cmd_work); -- cgit v1.2.3-59-g8ed1b From 05fcd4c4f1011858fe86dd7423304d8cae8e8d2e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 25 Oct 2015 23:29:22 +0100 Subject: Bluetooth: Replace hci_notify with hci_sock_dev_event There is no point in wrapping hci_sock_dev_event around hci_notify. It is an empty wrapper which adds no value. So remove it. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/hci_core.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) (limited to 'net') diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 3604e0194f87..83a6aacfab31 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -65,13 +65,6 @@ static DEFINE_IDA(hci_index_ida); #define hci_req_lock(d) mutex_lock(&d->req_lock) #define hci_req_unlock(d) mutex_unlock(&d->req_lock) -/* ---- HCI notifications ---- */ - -static void hci_notify(struct hci_dev *hdev, int event) -{ - hci_sock_dev_event(hdev, event); -} - /* ---- HCI debugfs entries ---- */ static ssize_t dut_mode_read(struct file *file, char __user *user_buf, @@ -1455,7 +1448,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) } set_bit(HCI_RUNNING, &hdev->flags); - hci_notify(hdev, HCI_DEV_OPEN); + hci_sock_dev_event(hdev, HCI_DEV_OPEN); atomic_set(&hdev->cmd_cnt, 1); set_bit(HCI_INIT, &hdev->flags); @@ -1524,7 +1517,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) hci_dev_hold(hdev); hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); set_bit(HCI_UP, &hdev->flags); - hci_notify(hdev, HCI_DEV_UP); + hci_sock_dev_event(hdev, HCI_DEV_UP); if (!hci_dev_test_flag(hdev, HCI_SETUP) && !hci_dev_test_flag(hdev, HCI_CONFIG) && !hci_dev_test_flag(hdev, HCI_UNCONFIGURED) && @@ -1552,7 +1545,7 @@ static int hci_dev_do_open(struct hci_dev *hdev) } clear_bit(HCI_RUNNING, &hdev->flags); - hci_notify(hdev, HCI_DEV_CLOSE); + hci_sock_dev_event(hdev, HCI_DEV_CLOSE); hdev->close(hdev); hdev->flags &= BIT(HCI_RAW); @@ -1708,7 +1701,7 @@ int hci_dev_do_close(struct hci_dev *hdev) smp_unregister(hdev); - hci_notify(hdev, HCI_DEV_DOWN); + hci_sock_dev_event(hdev, HCI_DEV_DOWN); if (hdev->flush) hdev->flush(hdev); @@ -1739,7 +1732,7 @@ int hci_dev_do_close(struct hci_dev *hdev) } clear_bit(HCI_RUNNING, &hdev->flags); - hci_notify(hdev, HCI_DEV_CLOSE); + hci_sock_dev_event(hdev, HCI_DEV_CLOSE); /* After this point our queues are empty * and no tasks are scheduled. */ @@ -3414,7 +3407,7 @@ int hci_register_dev(struct hci_dev *hdev) if (test_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks)) hci_dev_set_flag(hdev, HCI_UNCONFIGURED); - hci_notify(hdev, HCI_DEV_REG); + hci_sock_dev_event(hdev, HCI_DEV_REG); hci_dev_hold(hdev); queue_work(hdev->req_workqueue, &hdev->power_on); @@ -3462,7 +3455,7 @@ void hci_unregister_dev(struct hci_dev *hdev) * pending list */ BUG_ON(!list_empty(&hdev->mgmt_pending)); - hci_notify(hdev, HCI_DEV_UNREG); + hci_sock_dev_event(hdev, HCI_DEV_UNREG); if (hdev->rfkill) { rfkill_unregister(hdev->rfkill); @@ -3499,7 +3492,7 @@ EXPORT_SYMBOL(hci_unregister_dev); /* Suspend HCI device */ int hci_suspend_dev(struct hci_dev *hdev) { - hci_notify(hdev, HCI_DEV_SUSPEND); + hci_sock_dev_event(hdev, HCI_DEV_SUSPEND); return 0; } EXPORT_SYMBOL(hci_suspend_dev); @@ -3507,7 +3500,7 @@ EXPORT_SYMBOL(hci_suspend_dev); /* Resume HCI device */ int hci_resume_dev(struct hci_dev *hdev) { - hci_notify(hdev, HCI_DEV_RESUME); + hci_sock_dev_event(hdev, HCI_DEV_RESUME); return 0; } EXPORT_SYMBOL(hci_resume_dev); -- cgit v1.2.3-59-g8ed1b From c4297e8f7f453c83a75c2cbd93e57d8d9f36a316 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 26 Oct 2015 02:08:38 +0100 Subject: Bluetooth: Fix some obvious coding style issues in the SCO module Lets fix this obvious coding style issues in the SCO module and bring it in line with the rest of the Bluetooth subsystem. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- net/bluetooth/sco.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'net') diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 75f843d5423a..8ec10049bc24 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -74,7 +74,7 @@ struct sco_pinfo { static void sco_sock_timeout(unsigned long arg) { - struct sock *sk = (struct sock *) arg; + struct sock *sk = (struct sock *)arg; BT_DBG("sock %p state %d", sk, sk->sk_state); @@ -183,7 +183,8 @@ static void sco_conn_del(struct hci_conn *hcon, int err) kfree(conn); } -static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) +static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, + struct sock *parent) { BT_DBG("conn %p", conn); @@ -463,7 +464,8 @@ static struct proto sco_proto = { .obj_size = sizeof(struct sco_pinfo) }; -static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio, int kern) +static struct sock *sco_sock_alloc(struct net *net, struct socket *sock, + int proto, gfp_t prio, int kern) { struct sock *sk; @@ -512,7 +514,8 @@ static int sco_sock_create(struct net *net, struct socket *sock, int protocol, return 0; } -static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) +static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, + int addr_len) { struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; @@ -619,7 +622,8 @@ done: return err; } -static int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags) +static int sco_sock_accept(struct socket *sock, struct socket *newsock, + int flags) { DEFINE_WAIT_FUNC(wait, woken_wake_function); struct sock *sk = sock->sk, *ch; @@ -673,7 +677,8 @@ done: return err; } -static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) +static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, + int *len, int peer) { struct sockaddr_sco *sa = (struct sockaddr_sco *) addr; struct sock *sk = sock->sk; @@ -783,7 +788,8 @@ static int sco_sock_recvmsg(struct socket *sock, struct msghdr *msg, return bt_sock_recvmsg(sock, msg, len, flags); } -static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) +static int sco_sock_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int len, err = 0; @@ -823,7 +829,7 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char voice.setting = sco_pi(sk)->setting; len = min_t(unsigned int, sizeof(voice), optlen); - if (copy_from_user((char *) &voice, optval, len)) { + if (copy_from_user((char *)&voice, optval, len)) { err = -EFAULT; break; } @@ -847,7 +853,8 @@ static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char return err; } -static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) +static int sco_sock_getsockopt_old(struct socket *sock, int optname, + char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; struct sco_options opts; @@ -907,7 +914,8 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user return err; } -static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) +static int sco_sock_getsockopt(struct socket *sock, int level, int optname, + char __user *optval, int __user *optlen) { struct sock *sk = sock->sk; int len, err = 0; @@ -932,7 +940,7 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char } if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags), - (u32 __user *) optval)) + (u32 __user *)optval)) err = -EFAULT; break; -- cgit v1.2.3-59-g8ed1b From 2c501cdd6823a644cf35ac594c635310bf077125 Mon Sep 17 00:00:00 2001 From: Kuba Pawlak Date: Mon, 26 Oct 2015 16:17:14 +0000 Subject: Bluetooth: Fix crash on fast disconnect of SCO Fix a crash that may happen when a connection is closed before it was fully established. Mapping conn->hcon was released by shutdown function, but it is still referenced in (not yet finished) connection established handling function. [ 4635.254073] BUG: unable to handle kernel NULL pointer dereference at 00000013 [ 4635.262058] IP: [] memcmp+0xe/0x25 [ 4635.266835] *pdpt = 0000000024190001 *pde = 0000000000000000 [ 4635.273261] Oops: 0000 [#1] PREEMPT SMP [ 4635.277652] Modules linked in: evdev ecb vfat fat libcomposite usb2380 isofs zlib_inflate rfcomm(O) udc_core bnep(O) btusb(O) btbcm(O) btintel(O) bluetooth(O) cdc_acm arc4 uinput hid_mule [ 4635.321761] Pid: 363, comm: kworker/u:2H Tainted: G O 3.8.0-119.1-plk-adaptation-byt-ivi-brd #1 [ 4635.332642] EIP: 0060:[] EFLAGS: 00010206 CPU: 0 [ 4635.338767] EIP is at memcmp+0xe/0x25 [ 4635.342852] EAX: e4720678 EBX: 00000000 ECX: 00000006 EDX: 00000013 [ 4635.349849] ESI: 00000000 EDI: fb85366c EBP: e40c7dc0 ESP: e40c7db4 [ 4635.356846] DS: 007b ES: 007b FS: 00d8 GS: 0000 SS: 0068 [ 4635.362873] CR0: 8005003b CR2: 00000013 CR3: 24191000 CR4: 001007f0 [ 4635.369869] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [ 4635.376865] DR6: ffff0ff0 DR7: 00000400 [ 4635.381143] Process kworker/u:2H (pid: 363, ti=e40c6000 task=e40c5510 task.ti=e40c6000) [ 4635.390080] Stack: [ 4635.392319] e4720400 00000000 fb85366c e40c7df4 fb842285 e40c7de2 fb853200 00000013 [ 4635.401003] e3f101c4 e4720678 e3f101c0 e403be0a e40c7dfc e416a000 e403be0a fb85366c [ 4635.409692] e40c7e1c fb820186 020f6c00 e47c49ac e47c4008 00000000 e416a000 e47c402c [ 4635.418380] Call Trace: [ 4635.421153] [] sco_connect_cfm+0xff/0x236 [bluetooth] [ 4635.427893] [] hci_sync_conn_complete_evt.clone.101+0x227/0x268 [bluetooth] [ 4635.436758] [] hci_event_packet+0x1caa/0x21d3 [bluetooth] [ 4635.443859] [] ? trace_hardirqs_on+0xb/0xd [ 4635.449502] [] ? _raw_spin_unlock_irqrestore+0x42/0x59 [ 4635.456340] [] hci_rx_work+0xb9/0x350 [bluetooth] [ 4635.462663] [] ? process_one_work+0x17b/0x2e6 [ 4635.468596] [] process_one_work+0x1d4/0x2e6 [ 4635.474333] [] ? process_one_work+0x17b/0x2e6 [ 4635.480294] [] ? hci_cmd_work+0xda/0xda [bluetooth] [ 4635.486810] [] worker_thread+0x171/0x20f [ 4635.492257] [] ? complete+0x34/0x3e [ 4635.497219] [] kthread+0x90/0x95 [ 4635.501888] [] ? manage_workers+0x1df/0x1df [ 4635.507628] [] ret_from_kernel_thread+0x1b/0x28 [ 4635.513755] [] ? __init_kthread_worker+0x42/0x42 [ 4635.519975] Code: 74 0d 3c 79 74 04 3c 59 75 0c c6 02 01 eb 03 c6 02 00 31 c0 eb 05 b8 ea ff ff ff 5d c3 55 89 e5 57 56 53 31 db eb 0e 0f b6 34 18 <0f> b6 3c 1a 43 29 fe 75 07 49 85 c9 7f [ 4635.541264] EIP: [] memcmp+0xe/0x25 SS:ESP 0068:e40c7db4 [ 4635.548166] CR2: 0000000000000013 [ 4635.552177] ---[ end trace e05ce9b8ce6182f6 ]--- Signed-off-by: Kuba Pawlak Signed-off-by: Marcel Holtmann --- net/bluetooth/sco.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'net') diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 8ec10049bc24..fe129663bd3f 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -1033,6 +1033,11 @@ static void sco_conn_ready(struct sco_conn *conn) } else { sco_conn_lock(conn); + if (!conn->hcon) { + sco_conn_unlock(conn); + return; + } + parent = sco_get_sock_listen(&conn->hcon->src); if (!parent) { sco_conn_unlock(conn); -- cgit v1.2.3-59-g8ed1b From 324e786ee39c70ffbdc280c34b7d2b6da5c87879 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 27 Oct 2015 08:35:24 +0100 Subject: bluetooth: 6lowpan: fix NOHZ: local_softirq_pending Jukka reported about the following warning: "NOHZ: local_softirq_pending 08" I remember this warning and we had a similar issue when using workqueues and calling netif_rx. See commit 5ff3fec ("mac802154: fix NOHZ local_softirq_pending 08 warning"). This warning occurs when calling "netif_rx" inside the wrong context (non softirq context). The net core api offers "netif_rx_ni" to call netif_rx inside the correct softirq context. Reported-by: Jukka Rissanen Signed-off-by: Alexander Aring Acked-by: Jukka Rissanen Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index d85af2385486..9e9cca3689a0 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -263,7 +263,7 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev) if (!skb_cp) return NET_RX_DROP; - return netif_rx(skb_cp); + return netif_rx_ni(skb_cp); } static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev, -- cgit v1.2.3-59-g8ed1b