Skip to content

Commit 47afe93

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: HCI: Use skb_pull_data to parse LE Advertising Report event
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 <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 12cfe41 commit 47afe93

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

include/net/bluetooth/hci.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2445,13 +2445,18 @@ struct hci_ev_le_conn_complete {
24452445

24462446
#define HCI_EV_LE_ADVERTISING_REPORT 0x02
24472447
struct hci_ev_le_advertising_info {
2448-
__u8 evt_type;
2448+
__u8 type;
24492449
__u8 bdaddr_type;
24502450
bdaddr_t bdaddr;
24512451
__u8 length;
24522452
__u8 data[];
24532453
} __packed;
24542454

2455+
struct hci_ev_le_advertising_report {
2456+
__u8 num;
2457+
struct hci_ev_le_advertising_info info[];
2458+
} __packed;
2459+
24552460
#define HCI_EV_LE_CONN_UPDATE_COMPLETE 0x03
24562461
struct hci_ev_le_conn_update_complete {
24572462
__u8 status;

net/bluetooth/hci_event.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6564,31 +6564,40 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
65646564

65656565
static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
65666566
{
6567-
u8 num_reports = skb->data[0];
6568-
void *ptr = &skb->data[1];
6567+
struct hci_ev_le_advertising_report *ev;
6568+
6569+
ev = hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
6570+
sizeof(*ev));
6571+
if (!ev)
6572+
return;
6573+
6574+
if (!ev->num)
6575+
return;
65696576

65706577
hci_dev_lock(hdev);
65716578

6572-
while (num_reports--) {
6573-
struct hci_ev_le_advertising_info *ev = ptr;
6579+
while (ev->num--) {
6580+
struct hci_ev_le_advertising_info *info;
65746581
s8 rssi;
65756582

6576-
if (ptr > (void *)skb_tail_pointer(skb) - sizeof(*ev)) {
6577-
bt_dev_err(hdev, "Malicious advertising data.");
6583+
info = hci_le_ev_skb_pull(hdev, skb,
6584+
HCI_EV_LE_ADVERTISING_REPORT,
6585+
sizeof(*info));
6586+
if (!info)
65786587
break;
6579-
}
65806588

6581-
if (ev->length <= HCI_MAX_AD_LENGTH &&
6582-
ev->data + ev->length <= skb_tail_pointer(skb)) {
6583-
rssi = ev->data[ev->length];
6584-
process_adv_report(hdev, ev->evt_type, &ev->bdaddr,
6585-
ev->bdaddr_type, NULL, 0, rssi,
6586-
ev->data, ev->length, false);
6589+
if (!hci_le_ev_skb_pull(hdev, skb, HCI_EV_LE_ADVERTISING_REPORT,
6590+
info->length + 1))
6591+
break;
6592+
6593+
if (info->length <= HCI_MAX_AD_LENGTH) {
6594+
rssi = info->data[info->length];
6595+
process_adv_report(hdev, info->type, &info->bdaddr,
6596+
info->bdaddr_type, NULL, 0, rssi,
6597+
info->data, info->length, false);
65876598
} else {
65886599
bt_dev_err(hdev, "Dropping invalid advertising data");
65896600
}
6590-
6591-
ptr += sizeof(*ev) + ev->length + 1;
65926601
}
65936602

65946603
hci_dev_unlock(hdev);

0 commit comments

Comments
 (0)