Skip to content

Commit

Permalink
Bluetooth: HCI: Use skb_pull_data to parse LE Advertising Report event
Browse files Browse the repository at this point in the history
This uses skb_pull_data to check the LE Advertising Report events
received have the minimum required length.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Luiz Augusto von Dentz authored and Marcel Holtmann committed Dec 7, 2021
1 parent 12cfe41 commit 47afe93
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 16 deletions.
7 changes: 6 additions & 1 deletion include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -2445,13 +2445,18 @@ struct hci_ev_le_conn_complete {

#define HCI_EV_LE_ADVERTISING_REPORT 0x02
struct hci_ev_le_advertising_info {
__u8 evt_type;
__u8 type;
__u8 bdaddr_type;
bdaddr_t bdaddr;
__u8 length;
__u8 data[];
} __packed;

struct hci_ev_le_advertising_report {
__u8 num;
struct hci_ev_le_advertising_info info[];
} __packed;

#define HCI_EV_LE_CONN_UPDATE_COMPLETE 0x03
struct hci_ev_le_conn_update_complete {
__u8 status;
Expand Down
39 changes: 24 additions & 15 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -6564,31 +6564,40 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,

static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
u8 num_reports = skb->data[0];
void *ptr = &skb->data[1];
struct hci_ev_le_advertising_report *ev;

ev = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
sizeof(*ev));
if (!ev)
return;

if (!ev->num)
return;

hci_dev_lock(hdev);

while (num_reports--) {
struct hci_ev_le_advertising_info *ev = ptr;
while (ev->num--) {
struct hci_ev_le_advertising_info *info;
s8 rssi;

if (ptr > (void *)skb_tail_pointer(skb) - sizeof(*ev)) {
bt_dev_err(hdev, "Malicious advertising data.");
info = hci_le_ev_skb_pull(hdev, skb,
HCI_EV_LE_ADVERTISING_REPORT,
sizeof(*info));
if (!info)
break;
}

if (ev->length <= HCI_MAX_AD_LENGTH &&
ev->data + ev->length <= skb_tail_pointer(skb)) {
rssi = ev->data[ev->length];
process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
ev->bdaddr_type, NULL, 0, rssi,
ev->data, ev->length, false);
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
info->length + 1))
break;

if (info->length <= HCI_MAX_AD_LENGTH) {
rssi = info->data[info->length];
process_adv_report(hdev, info->type, &info->bdaddr,
info->bdaddr_type, NULL, 0, rssi,
info->data, info->length, false);
} else {
bt_dev_err(hdev, "Dropping invalid advertising data");
}

ptr += sizeof(*ev) + ev->length + 1;
}

hci_dev_unlock(hdev);
Expand Down

0 comments on commit 47afe93

Please sign in to comment.