aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-09-05 15:19:52 -0400
committerMarcel Holtmann <marcel@holtmann.org>2014-09-08 13:07:56 -0400
commitfc75cc8684d21d3649b28c4c37d4ce3f000759e4 (patch)
tree267b276a766d2808c0bda27d414acc358fab5154 /net
parentd6268e86a12a94a4f5193551c2367162e6a37db4 (diff)
Bluetooth: Fix locking of the SMP context
Before the move the l2cap_chan the SMP context (smp_chan) didn't have any kind of proper locking. The best there existed was the HCI_CONN_LE_SMP_PEND flag which was used to enable mutual exclusion for potential multiple creators of the SMP context. Now that SMP has been converted to use the l2cap_chan infrastructure and since the SMP context is directly mapped to a corresponding l2cap_chan we get the SMP context locking essentially for free through the l2cap_chan lock. For all callbacks that l2cap_core.c makes for each channel implementation (smp.c in the case of SMP) the l2cap_chan lock is held through l2cap_chan_lock(chan). Since the calls from l2cap_core.c to smp.c are covered the only missing piece to have the locking implemented properly is to ensure that the lock is held for any other call path that may access the SMP context. This means user responses through mgmt.c, requests to elevate the security of a connection through hci_conn.c, as well as any deferred work through workqueues. This patch adds the necessary locking to all these other code paths that try to access the SMP context. Since mutual exclusion for the l2cap_chan access is now covered from all directions the patch also removes unnecessary HCI_CONN_LE_SMP_PEND flag (once we've acquired the chan lock we can simply check whether chan->smp is set to know if there's an SMP context). Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/smp.c76
1 files changed, 44 insertions, 32 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 0b4403f3dce1..c71589f4b435 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -409,7 +409,6 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason)
409{ 409{
410 struct hci_conn *hcon = conn->hcon; 410 struct hci_conn *hcon = conn->hcon;
411 struct l2cap_chan *chan = conn->smp; 411 struct l2cap_chan *chan = conn->smp;
412 struct smp_chan *smp;
413 412
414 if (reason) 413 if (reason)
415 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), 414 smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
@@ -419,12 +418,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason)
419 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, 418 mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type,
420 HCI_ERROR_AUTH_FAILURE); 419 HCI_ERROR_AUTH_FAILURE);
421 420
422 if (!chan->data) 421 if (chan->data)
423 return;
424
425 smp = chan->data;
426
427 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
428 smp_chan_destroy(conn); 422 smp_chan_destroy(conn);
429} 423}
430 424
@@ -706,9 +700,6 @@ static void smp_distribute_keys(struct smp_chan *smp)
706 700
707 BT_DBG("conn %p", conn); 701 BT_DBG("conn %p", conn);
708 702
709 if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags))
710 return;
711
712 rsp = (void *) &smp->prsp[1]; 703 rsp = (void *) &smp->prsp[1];
713 704
714 /* The responder sends its keys first */ 705 /* The responder sends its keys first */
@@ -801,7 +792,6 @@ static void smp_distribute_keys(struct smp_chan *smp)
801 if ((smp->remote_key_dist & 0x07)) 792 if ((smp->remote_key_dist & 0x07))
802 return; 793 return;
803 794
804 clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags);
805 set_bit(SMP_FLAG_COMPLETE, &smp->flags); 795 set_bit(SMP_FLAG_COMPLETE, &smp->flags);
806 smp_notify_keys(conn); 796 smp_notify_keys(conn);
807 797
@@ -825,16 +815,13 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
825 struct smp_chan *smp; 815 struct smp_chan *smp;
826 816
827 smp = kzalloc(sizeof(*smp), GFP_ATOMIC); 817 smp = kzalloc(sizeof(*smp), GFP_ATOMIC);
828 if (!smp) { 818 if (!smp)
829 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
830 return NULL; 819 return NULL;
831 }
832 820
833 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); 821 smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC);
834 if (IS_ERR(smp->tfm_aes)) { 822 if (IS_ERR(smp->tfm_aes)) {
835 BT_ERR("Unable to create ECB crypto context"); 823 BT_ERR("Unable to create ECB crypto context");
836 kfree(smp); 824 kfree(smp);
837 clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags);
838 return NULL; 825 return NULL;
839 } 826 }
840 827
@@ -854,16 +841,23 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
854 struct l2cap_chan *chan; 841 struct l2cap_chan *chan;
855 struct smp_chan *smp; 842 struct smp_chan *smp;
856 u32 value; 843 u32 value;
844 int err;
857 845
858 BT_DBG(""); 846 BT_DBG("");
859 847
860 if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 848 if (!conn)
861 return -ENOTCONN; 849 return -ENOTCONN;
862 850
863 chan = conn->smp; 851 chan = conn->smp;
864 if (!chan) 852 if (!chan)
865 return -ENOTCONN; 853 return -ENOTCONN;
866 854
855 l2cap_chan_lock(chan);
856 if (!chan->data) {
857 err = -ENOTCONN;
858 goto unlock;
859 }
860
867 smp = chan->data; 861 smp = chan->data;
868 862
869 switch (mgmt_op) { 863 switch (mgmt_op) {
@@ -879,12 +873,16 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
879 case MGMT_OP_USER_PASSKEY_NEG_REPLY: 873 case MGMT_OP_USER_PASSKEY_NEG_REPLY:
880 case MGMT_OP_USER_CONFIRM_NEG_REPLY: 874 case MGMT_OP_USER_CONFIRM_NEG_REPLY:
881 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 875 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
882 return 0; 876 err = 0;
877 goto unlock;
883 default: 878 default:
884 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); 879 smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
885 return -EOPNOTSUPP; 880 err = -EOPNOTSUPP;
881 goto unlock;
886 } 882 }
887 883
884 err = 0;
885
888 /* If it is our turn to send Pairing Confirm, do so now */ 886 /* If it is our turn to send Pairing Confirm, do so now */
889 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { 887 if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) {
890 u8 rsp = smp_confirm(smp); 888 u8 rsp = smp_confirm(smp);
@@ -892,12 +890,15 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
892 smp_failure(conn, rsp); 890 smp_failure(conn, rsp);
893 } 891 }
894 892
895 return 0; 893unlock:
894 l2cap_chan_unlock(chan);
895 return err;
896} 896}
897 897
898static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) 898static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
899{ 899{
900 struct smp_cmd_pairing rsp, *req = (void *) skb->data; 900 struct smp_cmd_pairing rsp, *req = (void *) skb->data;
901 struct l2cap_chan *chan = conn->smp;
901 struct hci_dev *hdev = conn->hcon->hdev; 902 struct hci_dev *hdev = conn->hcon->hdev;
902 struct smp_chan *smp; 903 struct smp_chan *smp;
903 u8 key_size, auth, sec_level; 904 u8 key_size, auth, sec_level;
@@ -911,12 +912,10 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
911 if (conn->hcon->role != HCI_ROLE_SLAVE) 912 if (conn->hcon->role != HCI_ROLE_SLAVE)
912 return SMP_CMD_NOTSUPP; 913 return SMP_CMD_NOTSUPP;
913 914
914 if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { 915 if (!chan->data)
915 smp = smp_chan_create(conn); 916 smp = smp_chan_create(conn);
916 } else { 917 else
917 struct l2cap_chan *chan = conn->smp;
918 smp = chan->data; 918 smp = chan->data;
919 }
920 919
921 if (!smp) 920 if (!smp)
922 return SMP_UNSPECIFIED; 921 return SMP_UNSPECIFIED;
@@ -1122,6 +1121,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
1122 struct smp_cmd_security_req *rp = (void *) skb->data; 1121 struct smp_cmd_security_req *rp = (void *) skb->data;
1123 struct smp_cmd_pairing cp; 1122 struct smp_cmd_pairing cp;
1124 struct hci_conn *hcon = conn->hcon; 1123 struct hci_conn *hcon = conn->hcon;
1124 struct l2cap_chan *chan = conn->smp;
1125 struct smp_chan *smp; 1125 struct smp_chan *smp;
1126 u8 sec_level; 1126 u8 sec_level;
1127 1127
@@ -1143,7 +1143,8 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
1143 if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 1143 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1144 return 0; 1144 return 0;
1145 1145
1146 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 1146 /* If SMP is already in progress ignore this request */
1147 if (chan->data)
1147 return 0; 1148 return 0;
1148 1149
1149 smp = smp_chan_create(conn); 1150 smp = smp_chan_create(conn);
@@ -1170,8 +1171,10 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
1170int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) 1171int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1171{ 1172{
1172 struct l2cap_conn *conn = hcon->l2cap_data; 1173 struct l2cap_conn *conn = hcon->l2cap_data;
1174 struct l2cap_chan *chan = conn->smp;
1173 struct smp_chan *smp; 1175 struct smp_chan *smp;
1174 __u8 authreq; 1176 __u8 authreq;
1177 int ret;
1175 1178
1176 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); 1179 BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
1177 1180
@@ -1192,12 +1195,19 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1192 if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) 1195 if (smp_ltk_encrypt(conn, hcon->pending_sec_level))
1193 return 0; 1196 return 0;
1194 1197
1195 if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) 1198 l2cap_chan_lock(chan);
1196 return 0; 1199
1200 /* If SMP is already in progress ignore this request */
1201 if (chan->data) {
1202 ret = 0;
1203 goto unlock;
1204 }
1197 1205
1198 smp = smp_chan_create(conn); 1206 smp = smp_chan_create(conn);
1199 if (!smp) 1207 if (!smp) {
1200 return 1; 1208 ret = 1;
1209 goto unlock;
1210 }
1201 1211
1202 authreq = seclevel_to_authreq(sec_level); 1212 authreq = seclevel_to_authreq(sec_level);
1203 1213
@@ -1223,8 +1233,11 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
1223 } 1233 }
1224 1234
1225 set_bit(SMP_FLAG_INITIATOR, &smp->flags); 1235 set_bit(SMP_FLAG_INITIATOR, &smp->flags);
1236 ret = 0;
1226 1237
1227 return 0; 1238unlock:
1239 l2cap_chan_unlock(chan);
1240 return ret;
1228} 1241}
1229 1242
1230static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) 1243static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
@@ -1315,7 +1328,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
1315 struct l2cap_chan *chan = conn->smp; 1328 struct l2cap_chan *chan = conn->smp;
1316 struct smp_chan *smp = chan->data; 1329 struct smp_chan *smp = chan->data;
1317 struct hci_conn *hcon = conn->hcon; 1330 struct hci_conn *hcon = conn->hcon;
1318 struct hci_dev *hdev = hcon->hdev;
1319 bdaddr_t rpa; 1331 bdaddr_t rpa;
1320 1332
1321 BT_DBG(""); 1333 BT_DBG("");
@@ -1430,7 +1442,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb)
1430 * returns an error). 1442 * returns an error).
1431 */ 1443 */
1432 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && 1444 if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ &&
1433 !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { 1445 !chan->data) {
1434 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); 1446 BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code);
1435 err = -EOPNOTSUPP; 1447 err = -EOPNOTSUPP;
1436 goto done; 1448 goto done;
@@ -1504,7 +1516,7 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err)
1504 1516
1505 BT_DBG("chan %p", chan); 1517 BT_DBG("chan %p", chan);
1506 1518
1507 if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) 1519 if (chan->data)
1508 smp_chan_destroy(conn); 1520 smp_chan_destroy(conn);
1509 1521
1510 conn->smp = NULL; 1522 conn->smp = NULL;