From: Greg Kroah-Hartman Date: Mon, 7 Jul 2014 18:59:53 +0000 (-0700) Subject: 3.15-stable patches X-Git-Tag: v3.4.98~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=677b31218d41c18d6f45f5ee6bd9fb68b3d91a5b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.15-stable patches added patches: bluetooth-allow-change-security-level-on-att_cid-in-slave-role.patch bluetooth-fix-deadlock-in-l2cap_conn_del.patch bluetooth-fix-locking-of-hdev-when-calling-into-smp-code.patch bluetooth-fix-setting-correct-authentication-information-for-smp-stk.patch bluetooth-refactor-discovery-stopping-into-its-own-function.patch bluetooth-reuse-hci_stop_discovery-function-when-cleaning-up-hci-state.patch --- diff --git a/queue-3.15/bluetooth-allow-change-security-level-on-att_cid-in-slave-role.patch b/queue-3.15/bluetooth-allow-change-security-level-on-att_cid-in-slave-role.patch new file mode 100644 index 00000000000..99feb1f4a0b --- /dev/null +++ b/queue-3.15/bluetooth-allow-change-security-level-on-att_cid-in-slave-role.patch @@ -0,0 +1,35 @@ +From 92d1372e1a9fec00e146b74e8b9ad7a385b9b37f Mon Sep 17 00:00:00 2001 +From: Marcin Kraglak +Date: Fri, 13 Jun 2014 14:08:22 +0200 +Subject: Bluetooth: Allow change security level on ATT_CID in slave role + +From: Marcin Kraglak + +commit 92d1372e1a9fec00e146b74e8b9ad7a385b9b37f upstream. + +Kernel supports SMP Security Request so don't block increasing security +when we are slave. + +Signed-off-by: Marcin Kraglak +Acked-by: Johan Hedberg +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/l2cap_sock.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/net/bluetooth/l2cap_sock.c ++++ b/net/bluetooth/l2cap_sock.c +@@ -787,11 +787,6 @@ static int l2cap_sock_setsockopt(struct + + /*change security for LE channels */ + if (chan->scid == L2CAP_CID_ATT) { +- if (!conn->hcon->out) { +- err = -EINVAL; +- break; +- } +- + if (smp_conn_security(conn->hcon, sec.level)) + break; + sk->sk_state = BT_CONFIG; diff --git a/queue-3.15/bluetooth-fix-deadlock-in-l2cap_conn_del.patch b/queue-3.15/bluetooth-fix-deadlock-in-l2cap_conn_del.patch new file mode 100644 index 00000000000..026b024f156 --- /dev/null +++ b/queue-3.15/bluetooth-fix-deadlock-in-l2cap_conn_del.patch @@ -0,0 +1,54 @@ +From 7ab56c3a6eccb215034b0cb096e0313441cbf2a4 Mon Sep 17 00:00:00 2001 +From: Jukka Taimisto +Date: Thu, 12 Jun 2014 10:15:13 +0000 +Subject: Bluetooth: Fix deadlock in l2cap_conn_del() + +From: Jukka Taimisto + +commit 7ab56c3a6eccb215034b0cb096e0313441cbf2a4 upstream. + +A deadlock occurs when PDU containing invalid SMP opcode is received on +Security Manager Channel over LE link and conn->pending_rx_work worker +has not run yet. + +When LE link is created l2cap_conn_ready() is called and before +returning it schedules conn->pending_rx_work worker to hdev->workqueue. +Incoming data to SMP fixed channel is handled by l2cap_recv_frame() +which calls smp_sig_channel() to handle the SMP PDU. If +smp_sig_channel() indicates failure l2cap_conn_del() is called to delete +the connection. When deleting the connection, l2cap_conn_del() purges +the pending_rx queue and calls flush_work() to wait for the +pending_rx_work worker to complete. + +Since incoming data is handled by a worker running from the same +workqueue as the pending_rx_work is being scheduled on, we will deadlock +on waiting for pending_rx_work to complete. + +This patch fixes the deadlock by calling cancel_work_sync() instead of +flush_work(). + +Signed-off-by: Jukka Taimisto +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/l2cap_core.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -1657,7 +1657,13 @@ static void l2cap_conn_del(struct hci_co + kfree_skb(conn->rx_skb); + + skb_queue_purge(&conn->pending_rx); +- flush_work(&conn->pending_rx_work); ++ ++ /* We can not call flush_work(&conn->pending_rx_work) here since we ++ * might block if we are running on a worker from the same workqueue ++ * pending_rx_work is waiting on. ++ */ ++ if (work_pending(&conn->pending_rx_work)) ++ cancel_work_sync(&conn->pending_rx_work); + + l2cap_unregister_all_users(conn); + diff --git a/queue-3.15/bluetooth-fix-locking-of-hdev-when-calling-into-smp-code.patch b/queue-3.15/bluetooth-fix-locking-of-hdev-when-calling-into-smp-code.patch new file mode 100644 index 00000000000..035fef9a0b7 --- /dev/null +++ b/queue-3.15/bluetooth-fix-locking-of-hdev-when-calling-into-smp-code.patch @@ -0,0 +1,40 @@ +From c73f94b8c093a615ce80eabbde0ac6eb9abfe31a Mon Sep 17 00:00:00 2001 +From: Johan Hedberg +Date: Fri, 13 Jun 2014 10:22:28 +0300 +Subject: Bluetooth: Fix locking of hdev when calling into SMP code + +From: Johan Hedberg + +commit c73f94b8c093a615ce80eabbde0ac6eb9abfe31a upstream. + +The SMP code expects hdev to be unlocked since e.g. crypto functions +will try to (re)lock it. Therefore, we need to release the lock before +calling into smp.c from mgmt.c. Without this we risk a deadlock whenever +the smp_user_confirm_reply() function is called. + +Signed-off-by: Johan Hedberg +Tested-by: Lukasz Rymanowski +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/mgmt.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -3032,8 +3032,13 @@ static int user_pairing_resp(struct sock + } + + if (addr->type == BDADDR_LE_PUBLIC || addr->type == BDADDR_LE_RANDOM) { +- /* Continue with pairing via SMP */ ++ /* Continue with pairing via SMP. The hdev lock must be ++ * released as SMP may try to recquire it for crypto ++ * purposes. ++ */ ++ hci_dev_unlock(hdev); + err = smp_user_confirm_reply(conn, mgmt_op, passkey); ++ hci_dev_lock(hdev); + + if (!err) + err = cmd_complete(sk, hdev->id, mgmt_op, diff --git a/queue-3.15/bluetooth-fix-setting-correct-authentication-information-for-smp-stk.patch b/queue-3.15/bluetooth-fix-setting-correct-authentication-information-for-smp-stk.patch new file mode 100644 index 00000000000..9545322036b --- /dev/null +++ b/queue-3.15/bluetooth-fix-setting-correct-authentication-information-for-smp-stk.patch @@ -0,0 +1,50 @@ +From fff3490f47810e2d34b91fb9e31103e923b11c2f Mon Sep 17 00:00:00 2001 +From: Johan Hedberg +Date: Tue, 10 Jun 2014 15:19:50 +0300 +Subject: Bluetooth: Fix setting correct authentication information for SMP STK + +From: Johan Hedberg + +commit fff3490f47810e2d34b91fb9e31103e923b11c2f upstream. + +When we store the STK in slave role we should set the correct +authentication information for it. If the pairing is producing a HIGH +security level the STK is considered authenticated, and otherwise it's +considered unauthenticated. This patch fixes the value passed to the +hci_add_ltk() function when adding the STK on the slave side. + +Signed-off-by: Johan Hedberg +Tested-by: Marcin Kraglak +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/smp.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/net/bluetooth/smp.c ++++ b/net/bluetooth/smp.c +@@ -533,7 +533,7 @@ static void random_work(struct work_stru + hci_le_start_enc(hcon, ediv, rand, stk); + hcon->enc_key_size = smp->enc_key_size; + } else { +- u8 stk[16]; ++ u8 stk[16], auth; + __le64 rand = 0; + __le16 ediv = 0; + +@@ -545,8 +545,13 @@ static void random_work(struct work_stru + memset(stk + smp->enc_key_size, 0, + SMP_MAX_ENC_KEY_SIZE - smp->enc_key_size); + ++ if (hcon->pending_sec_level == BT_SECURITY_HIGH) ++ auth = 1; ++ else ++ auth = 0; ++ + hci_add_ltk(hcon->hdev, &hcon->dst, hcon->dst_type, +- HCI_SMP_STK_SLAVE, 0, stk, smp->enc_key_size, ++ HCI_SMP_STK_SLAVE, auth, stk, smp->enc_key_size, + ediv, rand); + } + diff --git a/queue-3.15/bluetooth-refactor-discovery-stopping-into-its-own-function.patch b/queue-3.15/bluetooth-refactor-discovery-stopping-into-its-own-function.patch new file mode 100644 index 00000000000..f7a3deb5ed3 --- /dev/null +++ b/queue-3.15/bluetooth-refactor-discovery-stopping-into-its-own-function.patch @@ -0,0 +1,142 @@ +From 21a60d307ddc2180cfa542a995d943d1034cf5c5 Mon Sep 17 00:00:00 2001 +From: Johan Hedberg +Date: Tue, 10 Jun 2014 14:05:58 +0300 +Subject: Bluetooth: Refactor discovery stopping into its own function + +From: Johan Hedberg + +commit 21a60d307ddc2180cfa542a995d943d1034cf5c5 upstream. + +We'll need to reuse the same logic for stopping discovery also when +cleaning up HCI state when powering off. This patch refactors the code +out to its own function that can later (in a subsequent patch) be used +also for the power off case. + +Signed-off-by: Johan Hedberg +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/mgmt.c | 93 ++++++++++++++++++++++++++------------------------- + 1 file changed, 49 insertions(+), 44 deletions(-) + +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -1045,6 +1045,43 @@ static void clean_up_hci_complete(struct + } + } + ++static void hci_stop_discovery(struct hci_request *req) ++{ ++ struct hci_dev *hdev = req->hdev; ++ struct hci_cp_remote_name_req_cancel cp; ++ struct inquiry_entry *e; ++ ++ switch (hdev->discovery.state) { ++ case DISCOVERY_FINDING: ++ if (test_bit(HCI_INQUIRY, &hdev->flags)) { ++ hci_req_add(req, HCI_OP_INQUIRY_CANCEL, 0, NULL); ++ } else { ++ cancel_delayed_work(&hdev->le_scan_disable); ++ hci_req_add_le_scan_disable(req); ++ } ++ ++ break; ++ ++ case DISCOVERY_RESOLVING: ++ e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, ++ NAME_PENDING); ++ if (!e) ++ return; ++ ++ bacpy(&cp.bdaddr, &e->data.bdaddr); ++ hci_req_add(req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), ++ &cp); ++ ++ break; ++ ++ default: ++ /* Passive scanning */ ++ if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) ++ hci_req_add_le_scan_disable(req); ++ break; ++ } ++} ++ + static int clean_up_hci_state(struct hci_dev *hdev) + { + struct hci_request req; +@@ -3570,8 +3607,6 @@ static int stop_discovery(struct sock *s + { + struct mgmt_cp_stop_discovery *mgmt_cp = data; + struct pending_cmd *cmd; +- struct hci_cp_remote_name_req_cancel cp; +- struct inquiry_entry *e; + struct hci_request req; + int err; + +@@ -3601,52 +3636,22 @@ static int stop_discovery(struct sock *s + + hci_req_init(&req, hdev); + +- switch (hdev->discovery.state) { +- case DISCOVERY_FINDING: +- if (test_bit(HCI_INQUIRY, &hdev->flags)) { +- hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL); +- } else { +- cancel_delayed_work(&hdev->le_scan_disable); +- +- hci_req_add_le_scan_disable(&req); +- } +- +- break; +- +- case DISCOVERY_RESOLVING: +- e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, +- NAME_PENDING); +- if (!e) { +- mgmt_pending_remove(cmd); +- err = cmd_complete(sk, hdev->id, +- MGMT_OP_STOP_DISCOVERY, 0, +- &mgmt_cp->type, +- sizeof(mgmt_cp->type)); +- hci_discovery_set_state(hdev, DISCOVERY_STOPPED); +- goto unlock; +- } +- +- bacpy(&cp.bdaddr, &e->data.bdaddr); +- hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), +- &cp); +- +- break; ++ hci_stop_discovery(&req); + +- default: +- BT_DBG("unknown discovery state %u", hdev->discovery.state); +- +- mgmt_pending_remove(cmd); +- err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, +- MGMT_STATUS_FAILED, &mgmt_cp->type, +- sizeof(mgmt_cp->type)); ++ err = hci_req_run(&req, stop_discovery_complete); ++ if (!err) { ++ hci_discovery_set_state(hdev, DISCOVERY_STOPPING); + goto unlock; + } + +- err = hci_req_run(&req, stop_discovery_complete); +- if (err < 0) +- mgmt_pending_remove(cmd); +- else +- hci_discovery_set_state(hdev, DISCOVERY_STOPPING); ++ mgmt_pending_remove(cmd); ++ ++ /* If no HCI commands were sent we're done */ ++ if (err == -ENODATA) { ++ err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, 0, ++ &mgmt_cp->type, sizeof(mgmt_cp->type)); ++ hci_discovery_set_state(hdev, DISCOVERY_STOPPED); ++ } + + unlock: + hci_dev_unlock(hdev); diff --git a/queue-3.15/bluetooth-reuse-hci_stop_discovery-function-when-cleaning-up-hci-state.patch b/queue-3.15/bluetooth-reuse-hci_stop_discovery-function-when-cleaning-up-hci-state.patch new file mode 100644 index 00000000000..ec27cc8bfe3 --- /dev/null +++ b/queue-3.15/bluetooth-reuse-hci_stop_discovery-function-when-cleaning-up-hci-state.patch @@ -0,0 +1,36 @@ +From f8680f128b01212895a9afb31032f6ffe91bd771 Mon Sep 17 00:00:00 2001 +From: Johan Hedberg +Date: Tue, 10 Jun 2014 14:05:59 +0300 +Subject: Bluetooth: Reuse hci_stop_discovery function when cleaning up HCI state + +From: Johan Hedberg + +commit f8680f128b01212895a9afb31032f6ffe91bd771 upstream. + +When cleaning up the HCI state as part of the power-off procedure we can +reuse the hci_stop_discovery() function instead of explicitly sending +HCI command related to discovery. The added benefit of this is that it +takes care of canceling name resolving and inquiry which were not +previously covered by the code. + +Signed-off-by: Johan Hedberg +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/mgmt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/net/bluetooth/mgmt.c ++++ b/net/bluetooth/mgmt.c +@@ -1098,9 +1098,7 @@ static int clean_up_hci_state(struct hci + if (test_bit(HCI_ADVERTISING, &hdev->dev_flags)) + disable_advertising(&req); + +- if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) { +- hci_req_add_le_scan_disable(&req); +- } ++ hci_stop_discovery(&req); + + list_for_each_entry(conn, &hdev->conn_hash.list, list) { + struct hci_cp_disconnect dc; diff --git a/queue-3.15/series b/queue-3.15/series index adbbf274d34..bf957e4d103 100644 --- a/queue-3.15/series +++ b/queue-3.15/series @@ -54,3 +54,9 @@ bluetooth-fix-incorrectly-overriding-conn-src_type.patch bluetooth-fix-ssp-acceptor-just-works-confirmation-without-mitm.patch bluetooth-fix-check-for-connection-encryption.patch bluetooth-fix-indicating-discovery-state-when-canceling-inquiry.patch +bluetooth-refactor-discovery-stopping-into-its-own-function.patch +bluetooth-reuse-hci_stop_discovery-function-when-cleaning-up-hci-state.patch +bluetooth-fix-setting-correct-authentication-information-for-smp-stk.patch +bluetooth-fix-deadlock-in-l2cap_conn_del.patch +bluetooth-fix-locking-of-hdev-when-calling-into-smp-code.patch +bluetooth-allow-change-security-level-on-att_cid-in-slave-role.patch