summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-02-18 10:19:37 +0200
committerMarcel Holtmann <marcel@holtmann.org>2014-02-18 00:47:03 -0800
commit6131ddc8eb9bad8c4ff37e097b2537c819b76cc0 (patch)
tree6bd8869c54b062c915472f6f7fde6b364cb10be4 /net
parentfd349c020c5b6f7a6e17cb8b4e821ff9b6f71ba6 (diff)
downloadop-kernel-dev-6131ddc8eb9bad8c4ff37e097b2537c819b76cc0.zip
op-kernel-dev-6131ddc8eb9bad8c4ff37e097b2537c819b76cc0.tar.gz
Bluetooth: Fix properly ignoring unexpected SMP PDUs
If we didn't request certain pieces of information during the key distribution negotiation we should properly ignore those PDUs if the peer incorrectly sends them. This includes the Encryption Information and Master Identification PDUs if the EncKey bit was not set, and the Identity Information and Identity Address Information PDUs if the IdKey bit was not set. 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.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 024baa7..5867c1c 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -891,6 +891,10 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
if (skb->len < sizeof(*rp))
return SMP_UNSPECIFIED;
+ /* Ignore this PDU if it wasn't requested */
+ if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
+ return 0;
+
skb_pull(skb, sizeof(*rp));
memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
@@ -911,6 +915,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
if (skb->len < sizeof(*rp))
return SMP_UNSPECIFIED;
+ /* Ignore this PDU if it wasn't requested */
+ if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
+ return 0;
+
skb_pull(skb, sizeof(*rp));
hci_dev_lock(hdev);
@@ -935,6 +943,10 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
if (skb->len < sizeof(*info))
return SMP_UNSPECIFIED;
+ /* Ignore this PDU if it wasn't requested */
+ if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
+ return 0;
+
skb_pull(skb, sizeof(*info));
memcpy(smp->irk, info->irk, 16);
@@ -955,6 +967,10 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
if (skb->len < sizeof(*info))
return SMP_UNSPECIFIED;
+ /* Ignore this PDU if it wasn't requested */
+ if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
+ return 0;
+
skb_pull(skb, sizeof(*info));
bacpy(&smp->id_addr, &info->bdaddr);
OpenPOWER on IntegriCloud