diff mbox series

[RFC,1/2] Bluetooth: Introduce bt_skb_pull

Message ID 20210412184033.2504931-1-luiz.dentz@gmail.com
State New
Headers show
Series [RFC,1/2] Bluetooth: Introduce bt_skb_pull | expand

Commit Message

Luiz Augusto von Dentz April 12, 2021, 6:40 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds bt_skb_pull which will be used to parse events, it checks
the skb contains the given length and then use skb_pull to advance in
data which avoid having to rely on another variable to track the
position in the buffer.

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
 include/net/bluetooth/bluetooth.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

bluez.test.bot@gmail.com April 12, 2021, 7:37 p.m. UTC | #1
This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=465841

---Test result---

##############################
Test: CheckPatch - PASS


##############################
Test: CheckGitLint - PASS


##############################
Test: CheckBuildK - PASS


##############################
Test: CheckTestRunner: Setup - PASS


##############################
Test: CheckTestRunner: l2cap-tester - PASS
Total: 40, Passed: 34 (85.0%), Failed: 0, Not Run: 6

##############################
Test: CheckTestRunner: bnep-tester - PASS
Total: 1, Passed: 1 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: mgmt-tester - PASS
Total: 416, Passed: 402 (96.6%), Failed: 0, Not Run: 14

##############################
Test: CheckTestRunner: rfcomm-tester - PASS
Total: 9, Passed: 9 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: sco-tester - PASS
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: smp-tester - PASS
Total: 8, Passed: 8 (100.0%), Failed: 0, Not Run: 0

##############################
Test: CheckTestRunner: userchan-tester - PASS
Total: 3, Passed: 3 (100.0%), Failed: 0, Not Run: 0



---
Regards,
Linux Bluetooth
Marcel Holtmann April 13, 2021, 7:08 p.m. UTC | #2
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@intel.com>

> ---

> 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.

> 	__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.

Regards

Marcel
Luiz Augusto von Dentz April 13, 2021, 9:15 p.m. UTC | #3
Hi Marcel,

On Tue, Apr 13, 2021 at 12:08 PM Marcel Holtmann <marcel@holtmann.org> wrote:
>

> 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@intel.com>

> > ---

> > 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.

> Regards

>

> Marcel

>



-- 
Luiz Augusto von Dentz
Marcel Holtmann April 14, 2021, 10:10 a.m. UTC | #4
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@intel.com>

>>> ---

>>> 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
Luiz Augusto von Dentz April 16, 2021, 8:44 p.m. UTC | #5
Hi Marcel,

On Wed, Apr 14, 2021 at 3:10 AM Marcel Holtmann <marcel@holtmann.org> wrote:
>

> 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@intel.com>

> >>> ---

> >>> 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.


Ive made the change and split the set to have the changes on a per
event level but that ends up creating way too many patches for my
liking (54 in total), I could perhaps squash them and only maintain
the changes to events where I had done more substantial changes.

> Regards

>

> Marcel

>



-- 
Luiz Augusto von Dentz
diff mbox series

Patch

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 9125effbf448..449bc8e112f9 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -420,6 +420,18 @@  static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk,
 	return NULL;
 }
 
+static inline void *bt_skb_pull(struct sk_buff *skb, size_t len)
+{
+	void *data = skb->data;
+
+	if (skb->len < len)
+		return NULL;
+
+	skb_pull(skb, len);
+
+	return data;
+}
+
 int bt_to_errno(u16 code);
 
 void hci_sock_set_flag(struct sock *sk, int nr);