@@ -3014,9 +3014,8 @@ static void btusb_coredump_qca(struct hci_dev *hdev)
30143014static int handle_dump_pkt_qca (struct hci_dev * hdev , struct sk_buff * skb )
30153015{
30163016 int ret = 0 ;
3017+ unsigned int skip = 0 ;
30173018 u8 pkt_type ;
3018- u8 * sk_ptr ;
3019- unsigned int sk_len ;
30203019 u16 seqno ;
30213020 u32 dump_size ;
30223021
@@ -3025,18 +3024,13 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30253024 struct usb_device * udev = btdata -> udev ;
30263025
30273026 pkt_type = hci_skb_pkt_type (skb );
3028- sk_ptr = skb -> data ;
3029- sk_len = skb -> len ;
3027+ skip = sizeof (struct hci_event_hdr );
3028+ if (pkt_type == HCI_ACLDATA_PKT )
3029+ skip += sizeof (struct hci_acl_hdr );
30303030
3031- if (pkt_type == HCI_ACLDATA_PKT ) {
3032- sk_ptr += HCI_ACL_HDR_SIZE ;
3033- sk_len -= HCI_ACL_HDR_SIZE ;
3034- }
3035-
3036- sk_ptr += HCI_EVENT_HDR_SIZE ;
3037- sk_len -= HCI_EVENT_HDR_SIZE ;
3031+ skb_pull (skb , skip );
3032+ dump_hdr = (struct qca_dump_hdr * )skb -> data ;
30383033
3039- dump_hdr = (struct qca_dump_hdr * )sk_ptr ;
30403034 seqno = le16_to_cpu (dump_hdr -> seqno );
30413035 if (seqno == 0 ) {
30423036 set_bit (BTUSB_HW_SSR_ACTIVE , & btdata -> flags );
@@ -3056,16 +3050,15 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30563050
30573051 btdata -> qca_dump .ram_dump_size = dump_size ;
30583052 btdata -> qca_dump .ram_dump_seqno = 0 ;
3059- sk_ptr += offsetof( struct qca_dump_hdr , data0 );
3060- sk_len -= offsetof(struct qca_dump_hdr , data0 );
3053+
3054+ skb_pull ( skb , offsetof(struct qca_dump_hdr , data0 ) );
30613055
30623056 usb_disable_autosuspend (udev );
30633057 bt_dev_info (hdev , "%s memdump size(%u)\n" ,
30643058 (pkt_type == HCI_ACLDATA_PKT ) ? "ACL" : "event" ,
30653059 dump_size );
30663060 } else {
3067- sk_ptr += offsetof(struct qca_dump_hdr , data );
3068- sk_len -= offsetof(struct qca_dump_hdr , data );
3061+ skb_pull (skb , offsetof(struct qca_dump_hdr , data ));
30693062 }
30703063
30713064 if (!btdata -> qca_dump .ram_dump_size ) {
@@ -3085,7 +3078,6 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
30853078 return ret ;
30863079 }
30873080
3088- skb_pull (skb , skb -> len - sk_len );
30893081 hci_devcd_append (hdev , skb );
30903082 btdata -> qca_dump .ram_dump_seqno ++ ;
30913083 if (seqno == QCA_LAST_SEQUENCE_NUM ) {
@@ -3113,68 +3105,58 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
31133105/* Return: true if the ACL packet is a dump packet, false otherwise. */
31143106static bool acl_pkt_is_dump_qca (struct hci_dev * hdev , struct sk_buff * skb )
31153107{
3116- u8 * sk_ptr ;
3117- unsigned int sk_len ;
3118-
31193108 struct hci_event_hdr * event_hdr ;
31203109 struct hci_acl_hdr * acl_hdr ;
31213110 struct qca_dump_hdr * dump_hdr ;
3111+ struct sk_buff * clone = skb_clone (skb , GFP_ATOMIC );
3112+ bool is_dump = false;
31223113
3123- sk_ptr = skb -> data ;
3124- sk_len = skb -> len ;
3125-
3126- acl_hdr = hci_acl_hdr (skb );
3127- if (le16_to_cpu (acl_hdr -> handle ) != QCA_MEMDUMP_ACL_HANDLE )
3114+ if (!clone )
31283115 return false;
31293116
3130- sk_ptr += HCI_ACL_HDR_SIZE ;
3131- sk_len -= HCI_ACL_HDR_SIZE ;
3132- event_hdr = (struct hci_event_hdr * )sk_ptr ;
3133-
3134- if ((event_hdr -> evt != HCI_VENDOR_PKT ) ||
3135- (event_hdr -> plen != (sk_len - HCI_EVENT_HDR_SIZE )))
3136- return false;
3117+ acl_hdr = skb_pull_data (clone , sizeof (* acl_hdr ));
3118+ if (!acl_hdr || (le16_to_cpu (acl_hdr -> handle ) != QCA_MEMDUMP_ACL_HANDLE ))
3119+ goto out ;
31373120
3138- sk_ptr += HCI_EVENT_HDR_SIZE ;
3139- sk_len -= HCI_EVENT_HDR_SIZE ;
3121+ event_hdr = skb_pull_data (clone , sizeof (* event_hdr ));
3122+ if (!event_hdr || (event_hdr -> evt != HCI_VENDOR_PKT ))
3123+ goto out ;
31403124
3141- dump_hdr = (struct qca_dump_hdr * )sk_ptr ;
3142- if ((sk_len < offsetof(struct qca_dump_hdr , data )) ||
3143- (dump_hdr -> vse_class != QCA_MEMDUMP_VSE_CLASS ) ||
3144- (dump_hdr -> msg_type != QCA_MEMDUMP_MSG_TYPE ))
3145- return false;
3125+ dump_hdr = skb_pull_data (clone , sizeof (* dump_hdr ));
3126+ if (!dump_hdr || (dump_hdr -> vse_class != QCA_MEMDUMP_VSE_CLASS ) ||
3127+ (dump_hdr -> msg_type != QCA_MEMDUMP_MSG_TYPE ))
3128+ goto out ;
31463129
3147- return true;
3130+ is_dump = true;
3131+ out :
3132+ consume_skb (clone );
3133+ return is_dump ;
31483134}
31493135
31503136/* Return: true if the event packet is a dump packet, false otherwise. */
31513137static bool evt_pkt_is_dump_qca (struct hci_dev * hdev , struct sk_buff * skb )
31523138{
3153- u8 * sk_ptr ;
3154- unsigned int sk_len ;
3155-
31563139 struct hci_event_hdr * event_hdr ;
31573140 struct qca_dump_hdr * dump_hdr ;
3141+ struct sk_buff * clone = skb_clone (skb , GFP_ATOMIC );
3142+ bool is_dump = false;
31583143
3159- sk_ptr = skb -> data ;
3160- sk_len = skb -> len ;
3161-
3162- event_hdr = hci_event_hdr (skb );
3163-
3164- if ((event_hdr -> evt != HCI_VENDOR_PKT )
3165- || (event_hdr -> plen != (sk_len - HCI_EVENT_HDR_SIZE )))
3144+ if (!clone )
31663145 return false;
31673146
3168- sk_ptr += HCI_EVENT_HDR_SIZE ;
3169- sk_len -= HCI_EVENT_HDR_SIZE ;
3147+ event_hdr = skb_pull_data (clone , sizeof (* event_hdr ));
3148+ if (!event_hdr || (event_hdr -> evt != HCI_VENDOR_PKT ))
3149+ goto out ;
31703150
3171- dump_hdr = (struct qca_dump_hdr * )sk_ptr ;
3172- if ((sk_len < offsetof(struct qca_dump_hdr , data )) ||
3173- (dump_hdr -> vse_class != QCA_MEMDUMP_VSE_CLASS ) ||
3174- (dump_hdr -> msg_type != QCA_MEMDUMP_MSG_TYPE ))
3175- return false;
3151+ dump_hdr = skb_pull_data (clone , sizeof (* dump_hdr ));
3152+ if (!dump_hdr || (dump_hdr -> vse_class != QCA_MEMDUMP_VSE_CLASS ) ||
3153+ (dump_hdr -> msg_type != QCA_MEMDUMP_MSG_TYPE ))
3154+ goto out ;
31763155
3177- return true;
3156+ is_dump = true;
3157+ out :
3158+ consume_skb (clone );
3159+ return is_dump ;
31783160}
31793161
31803162static int btusb_recv_acl_qca (struct hci_dev * hdev , struct sk_buff * skb )
0 commit comments