Re: [RFC 2/2] Bluetooth: HCI: Use bt_skb_pull to parse events

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Luiz,

>>> This uses bt_skb_pull to check the events received have the minimum
>>> required length, while at it also rework checks for flexible arrays to
>>> use flex_array_size.
>>> 
>>> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>
>>> ---
>>> include/net/bluetooth/hci.h |  59 ++-
>>> net/bluetooth/hci_event.c   | 848 ++++++++++++++++++++++++++++--------
>>> 2 files changed, 722 insertions(+), 185 deletions(-)
>>> 
>>> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
>>> index ea4ae551c426..13b7c7747bd1 100644
>>> --- a/include/net/bluetooth/hci.h
>>> +++ b/include/net/bluetooth/hci.h
>>> @@ -1894,6 +1894,10 @@ struct hci_cp_le_reject_cis {
>>> } __packed;
>>> 
>>> /* ---- HCI Events ---- */
>>> +struct hci_ev_status {
>>> +     __u8    status;
>>> +} __packed;
>>> +
>>> #define HCI_EV_INQUIRY_COMPLETE               0x01
>>> 
>>> #define HCI_EV_INQUIRY_RESULT         0x02
>>> @@ -1906,6 +1910,11 @@ struct inquiry_info {
>>>      __le16   clock_offset;
>>> } __packed;
>>> 
>>> +struct hci_ev_inquiry_result {
>>> +     __u8    num;
>>> +     struct inquiry_info info[];
>>> +};
>>> +
>>> #define HCI_EV_CONN_COMPLETE          0x03
>>> struct hci_ev_conn_complete {
>>>      __u8     status;
>>> @@ -2017,7 +2026,7 @@ struct hci_comp_pkts_info {
>>> } __packed;
>>> 
>>> struct hci_ev_num_comp_pkts {
>>> -     __u8     num_hndl;
>>> +     __u8     num;
>>>      struct hci_comp_pkts_info handles[];
>>> } __packed;
>>> 
>>> @@ -2067,7 +2076,7 @@ struct hci_ev_pscan_rep_mode {
>>> } __packed;
>>> 
>>> #define HCI_EV_INQUIRY_RESULT_WITH_RSSI       0x22
>>> -struct inquiry_info_with_rssi {
>>> +struct inquiry_info_rssi {
>>>      bdaddr_t bdaddr;
>>>      __u8     pscan_rep_mode;
>>>      __u8     pscan_period_mode;
>>> @@ -2075,7 +2084,7 @@ struct inquiry_info_with_rssi {
>>>      __le16   clock_offset;
>>>      __s8     rssi;
>>> } __packed;
>>> -struct inquiry_info_with_rssi_and_pscan_mode {
>>> +struct inquiry_info_rssi_pscan {
>>>      bdaddr_t bdaddr;
>>>      __u8     pscan_rep_mode;
>>>      __u8     pscan_period_mode;
>>> @@ -2084,6 +2093,14 @@ struct inquiry_info_with_rssi_and_pscan_mode {
>>>      __le16   clock_offset;
>>>      __s8     rssi;
>>> } __packed;
>>> +struct hci_ev_inquiry_result_rssi {
>>> +     __u8     num;
>>> +     struct inquiry_info_rssi info[];
>>> +} __packed;
>>> +struct hci_ev_inquiry_result_rssi_pscan {
>>> +     __u8     num;
>>> +     struct inquiry_info_rssi_pscan info[];
>>> +} __packed;
>>> 
>>> #define HCI_EV_REMOTE_EXT_FEATURES    0x23
>>> struct hci_ev_remote_ext_features {
>>> @@ -2138,6 +2155,11 @@ struct extended_inquiry_info {
>>>      __u8     data[240];
>>> } __packed;
>>> 
>>> +struct hci_ev_ext_inquiry_result {
>>> +     __u8     num;
>>> +     struct extended_inquiry_info info[];
>>> +} __packed;
>>> +
>>> #define HCI_EV_KEY_REFRESH_COMPLETE   0x30
>>> struct hci_ev_key_refresh_complete {
>>>      __u8    status;
>>> @@ -2305,13 +2327,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;
>>> @@ -2355,7 +2382,7 @@ struct hci_ev_le_data_len_change {
>>> 
>>> #define HCI_EV_LE_DIRECT_ADV_REPORT   0x0B
>>> struct hci_ev_le_direct_adv_info {
>>> -     __u8     evt_type;
>>> +     __u8     type;
>> 
>> these changes look unrelated. Prepare to send a prepare patch.
> 
> Yep, I might split the changes so I make each event into a separate
> patch since some changes require some changes in the struct (or just
> simplify the naming).
> 
>> 
>>>      __u8     bdaddr_type;
>>>      bdaddr_t bdaddr;
>>>      __u8     direct_addr_type;
>>> @@ -2363,6 +2390,11 @@ struct hci_ev_le_direct_adv_info {
>>>      __s8     rssi;
>>> } __packed;
>>> 
>>> +struct hci_ev_le_direct_adv_report {
>>> +     __u8     num;
>>> +     struct hci_ev_le_direct_adv_info info[];
>>> +} __packed;
>>> +
>>> #define HCI_EV_LE_PHY_UPDATE_COMPLETE 0x0c
>>> struct hci_ev_le_phy_update_complete {
>>>      __u8  status;
>>> @@ -2372,8 +2404,8 @@ struct hci_ev_le_phy_update_complete {
>>> } __packed;
>>> 
>>> #define HCI_EV_LE_EXT_ADV_REPORT    0x0d
>>> -struct hci_ev_le_ext_adv_report {
>>> -     __le16   evt_type;
>>> +struct hci_ev_le_ext_adv_info {
>>> +     __le16   type;
>>>      __u8     bdaddr_type;
>>>      bdaddr_t bdaddr;
>>>      __u8     primary_phy;
>>> @@ -2381,11 +2413,16 @@ struct hci_ev_le_ext_adv_report {
>>>      __u8     sid;
>>>      __u8     tx_power;
>>>      __s8     rssi;
>>> -     __le16   interval;
>>> -     __u8     direct_addr_type;
>>> +     __le16   interval;
>>> +     __u8     direct_addr_type;
>>>      bdaddr_t direct_addr;
>>> -     __u8     length;
>>> -     __u8     data[];
>>> +     __u8     length;
>>> +     __u8     data[];
>>> +} __packed;
>>> +
>>> +struct hci_ev_le_ext_adv_report {
>>> +     __u8     num;
>>> +     struct hci_ev_le_ext_adv_info info[];
>>> } __packed;
>>> 
>>> #define HCI_EV_LE_ENHANCED_CONN_COMPLETE    0x0a
>>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>>> index 5e99968939ce..db40358521fa 100644
>>> --- a/net/bluetooth/hci_event.c
>>> +++ b/net/bluetooth/hci_event.c
>>> @@ -45,9 +45,16 @@
>>> static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb,
>>>                                u8 *new_status)
>>> {
>>> -     __u8 status = *((__u8 *) skb->data);
>>> +     struct hci_ev_status *rp;
>>> 
>>> -     BT_DBG("%s status 0x%2.2x", hdev->name, status);
>>> +     rp = bt_skb_pull(skb, sizeof(*rp));
>>> +     if (!rp) {
>>> +             bt_dev_err(hdev, "Malformed Command Complete: 0x%4.4x",
>>> +                        HCI_OP_INQUIRY_CANCEL);
>>> +             return;
>>> +     }
>> 
>> So you are repeating this over and over again. The error needs to be part of bt_skb_pull and I would make bt_skb_pull static and local to hci_event.c.
> 
> Understood, would something like the following make sense:
> 
> static void *hci_ev_pull(skb, opcode, size)
> 
> The reason I had introduced bt_skb_pull as public function is that it
> may be convenient to parse packets in other protocols as well, but I
> guess it could be introduced later if we decide to expand this sort of
> logic to other protocols as well.

I would go with hci_ev_skb_pull() to make clear it operates on the skb.

Regards

Marcel




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux