diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-09-10 20:37:42 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-09-10 20:45:24 -0400 |
commit | c05b9339c8a448a2df0c8598424ea9c0933288d1 (patch) | |
tree | c37fc20b8ecc84f7c13a8b2e0915f96c3f399d2a /net/bluetooth/smp.c | |
parent | 3a7dbfb8ff943711be4221df978254ad2bc1ac46 (diff) |
Bluetooth: Fix ignoring unknown SMP authentication requirement bits
The SMP specification states that we should ignore any unknown bits from
the authentication requirement. We already have a define for masking out
unknown bits but we haven't used it in all places so far. This patch
adds usage of the AUTH_REQ_MASK to all places that need it and ensures
that we don't pass unknown bits onward to other functions.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r-- | net/bluetooth/smp.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index dbd17a07dc2e..ef8f96d2c059 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -949,8 +949,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
949 | if (!smp) | 949 | if (!smp) |
950 | return SMP_UNSPECIFIED; | 950 | return SMP_UNSPECIFIED; |
951 | 951 | ||
952 | /* We didn't start the pairing, so match remote */ | ||
953 | auth = req->auth_req & AUTH_REQ_MASK; | ||
954 | |||
952 | if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && | 955 | if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && |
953 | (req->auth_req & SMP_AUTH_BONDING)) | 956 | (auth & SMP_AUTH_BONDING)) |
954 | return SMP_PAIRING_NOTSUPP; | 957 | return SMP_PAIRING_NOTSUPP; |
955 | 958 | ||
956 | SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); | 959 | SMP_DISALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); |
@@ -959,9 +962,6 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
959 | memcpy(&smp->preq[1], req, sizeof(*req)); | 962 | memcpy(&smp->preq[1], req, sizeof(*req)); |
960 | skb_pull(skb, sizeof(*req)); | 963 | skb_pull(skb, sizeof(*req)); |
961 | 964 | ||
962 | /* We didn't start the pairing, so match remote */ | ||
963 | auth = req->auth_req; | ||
964 | |||
965 | sec_level = authreq_to_seclevel(auth); | 965 | sec_level = authreq_to_seclevel(auth); |
966 | if (sec_level > conn->hcon->pending_sec_level) | 966 | if (sec_level > conn->hcon->pending_sec_level) |
967 | conn->hcon->pending_sec_level = sec_level; | 967 | conn->hcon->pending_sec_level = sec_level; |
@@ -1024,6 +1024,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1024 | if (check_enc_key_size(conn, key_size)) | 1024 | if (check_enc_key_size(conn, key_size)) |
1025 | return SMP_ENC_KEY_SIZE; | 1025 | return SMP_ENC_KEY_SIZE; |
1026 | 1026 | ||
1027 | auth = rsp->auth_req & AUTH_REQ_MASK; | ||
1028 | |||
1027 | /* If we need MITM check that it can be acheived */ | 1029 | /* If we need MITM check that it can be acheived */ |
1028 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { | 1030 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { |
1029 | u8 method; | 1031 | u8 method; |
@@ -1044,7 +1046,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1044 | */ | 1046 | */ |
1045 | smp->remote_key_dist &= rsp->resp_key_dist; | 1047 | smp->remote_key_dist &= rsp->resp_key_dist; |
1046 | 1048 | ||
1047 | auth = (req->auth_req | rsp->auth_req); | 1049 | auth |= req->auth_req; |
1048 | 1050 | ||
1049 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); | 1051 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); |
1050 | if (ret) | 1052 | if (ret) |
@@ -1160,7 +1162,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1160 | struct smp_cmd_pairing cp; | 1162 | struct smp_cmd_pairing cp; |
1161 | struct hci_conn *hcon = conn->hcon; | 1163 | struct hci_conn *hcon = conn->hcon; |
1162 | struct smp_chan *smp; | 1164 | struct smp_chan *smp; |
1163 | u8 sec_level; | 1165 | u8 sec_level, auth; |
1164 | 1166 | ||
1165 | BT_DBG("conn %p", conn); | 1167 | BT_DBG("conn %p", conn); |
1166 | 1168 | ||
@@ -1170,7 +1172,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1170 | if (hcon->role != HCI_ROLE_MASTER) | 1172 | if (hcon->role != HCI_ROLE_MASTER) |
1171 | return SMP_CMD_NOTSUPP; | 1173 | return SMP_CMD_NOTSUPP; |
1172 | 1174 | ||
1173 | sec_level = authreq_to_seclevel(rp->auth_req); | 1175 | auth = rp->auth_req & AUTH_REQ_MASK; |
1176 | |||
1177 | sec_level = authreq_to_seclevel(auth); | ||
1174 | if (smp_sufficient_security(hcon, sec_level)) | 1178 | if (smp_sufficient_security(hcon, sec_level)) |
1175 | return 0; | 1179 | return 0; |
1176 | 1180 | ||
@@ -1185,13 +1189,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1185 | return SMP_UNSPECIFIED; | 1189 | return SMP_UNSPECIFIED; |
1186 | 1190 | ||
1187 | if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && | 1191 | if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && |
1188 | (rp->auth_req & SMP_AUTH_BONDING)) | 1192 | (auth & SMP_AUTH_BONDING)) |
1189 | return SMP_PAIRING_NOTSUPP; | 1193 | return SMP_PAIRING_NOTSUPP; |
1190 | 1194 | ||
1191 | skb_pull(skb, sizeof(*rp)); | 1195 | skb_pull(skb, sizeof(*rp)); |
1192 | 1196 | ||
1193 | memset(&cp, 0, sizeof(cp)); | 1197 | memset(&cp, 0, sizeof(cp)); |
1194 | build_pairing_cmd(conn, &cp, NULL, rp->auth_req); | 1198 | build_pairing_cmd(conn, &cp, NULL, auth); |
1195 | 1199 | ||
1196 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 1200 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
1197 | memcpy(&smp->preq[1], &cp, sizeof(cp)); | 1201 | memcpy(&smp->preq[1], &cp, sizeof(cp)); |