Commit 6131ddc8 authored by Johan Hedberg's avatar Johan Hedberg Committed by Marcel Holtmann

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: default avatarJohan Hedberg <johan.hedberg@intel.com>
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent fd349c02
...@@ -891,6 +891,10 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -891,6 +891,10 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
if (skb->len < sizeof(*rp)) if (skb->len < sizeof(*rp))
return SMP_UNSPECIFIED; 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)); skb_pull(skb, sizeof(*rp));
memcpy(smp->tk, rp->ltk, sizeof(smp->tk)); 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) ...@@ -911,6 +915,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
if (skb->len < sizeof(*rp)) if (skb->len < sizeof(*rp))
return SMP_UNSPECIFIED; 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)); skb_pull(skb, sizeof(*rp));
hci_dev_lock(hdev); hci_dev_lock(hdev);
...@@ -935,6 +943,10 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -935,6 +943,10 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
if (skb->len < sizeof(*info)) if (skb->len < sizeof(*info))
return SMP_UNSPECIFIED; 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)); skb_pull(skb, sizeof(*info));
memcpy(smp->irk, info->irk, 16); memcpy(smp->irk, info->irk, 16);
...@@ -955,6 +967,10 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, ...@@ -955,6 +967,10 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
if (skb->len < sizeof(*info)) if (skb->len < sizeof(*info))
return SMP_UNSPECIFIED; 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)); skb_pull(skb, sizeof(*info));
bacpy(&smp->id_addr, &info->bdaddr); bacpy(&smp->id_addr, &info->bdaddr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment