@@ -3014,9 +3014,8 @@ static void btusb_coredump_qca(struct hci_dev *hdev)
3014
3014
static int handle_dump_pkt_qca (struct hci_dev * hdev , struct sk_buff * skb )
3015
3015
{
3016
3016
int ret = 0 ;
3017
+ unsigned int skip = 0 ;
3017
3018
u8 pkt_type ;
3018
- u8 * sk_ptr ;
3019
- unsigned int sk_len ;
3020
3019
u16 seqno ;
3021
3020
u32 dump_size ;
3022
3021
@@ -3025,18 +3024,13 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
3025
3024
struct usb_device * udev = btdata -> udev ;
3026
3025
3027
3026
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 );
3030
3030
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 ;
3038
3033
3039
- dump_hdr = (struct qca_dump_hdr * )sk_ptr ;
3040
3034
seqno = le16_to_cpu (dump_hdr -> seqno );
3041
3035
if (seqno == 0 ) {
3042
3036
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)
3056
3050
3057
3051
btdata -> qca_dump .ram_dump_size = dump_size ;
3058
3052
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 ) );
3061
3055
3062
3056
usb_disable_autosuspend (udev );
3063
3057
bt_dev_info (hdev , "%s memdump size(%u)\n" ,
3064
3058
(pkt_type == HCI_ACLDATA_PKT ) ? "ACL" : "event" ,
3065
3059
dump_size );
3066
3060
} 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 ));
3069
3062
}
3070
3063
3071
3064
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)
3085
3078
return ret ;
3086
3079
}
3087
3080
3088
- skb_pull (skb , skb -> len - sk_len );
3089
3081
hci_devcd_append (hdev , skb );
3090
3082
btdata -> qca_dump .ram_dump_seqno ++ ;
3091
3083
if (seqno == QCA_LAST_SEQUENCE_NUM ) {
@@ -3113,68 +3105,58 @@ static int handle_dump_pkt_qca(struct hci_dev *hdev, struct sk_buff *skb)
3113
3105
/* Return: true if the ACL packet is a dump packet, false otherwise. */
3114
3106
static bool acl_pkt_is_dump_qca (struct hci_dev * hdev , struct sk_buff * skb )
3115
3107
{
3116
- u8 * sk_ptr ;
3117
- unsigned int sk_len ;
3118
-
3119
3108
struct hci_event_hdr * event_hdr ;
3120
3109
struct hci_acl_hdr * acl_hdr ;
3121
3110
struct qca_dump_hdr * dump_hdr ;
3111
+ struct sk_buff * clone = skb_clone (skb , GFP_ATOMIC );
3112
+ bool is_dump = false;
3122
3113
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 )
3128
3115
return false;
3129
3116
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 ;
3137
3120
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 ;
3140
3124
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 ;
3146
3129
3147
- return true;
3130
+ is_dump = true;
3131
+ out :
3132
+ consume_skb (clone );
3133
+ return is_dump ;
3148
3134
}
3149
3135
3150
3136
/* Return: true if the event packet is a dump packet, false otherwise. */
3151
3137
static bool evt_pkt_is_dump_qca (struct hci_dev * hdev , struct sk_buff * skb )
3152
3138
{
3153
- u8 * sk_ptr ;
3154
- unsigned int sk_len ;
3155
-
3156
3139
struct hci_event_hdr * event_hdr ;
3157
3140
struct qca_dump_hdr * dump_hdr ;
3141
+ struct sk_buff * clone = skb_clone (skb , GFP_ATOMIC );
3142
+ bool is_dump = false;
3158
3143
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 )
3166
3145
return false;
3167
3146
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 ;
3170
3150
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 ;
3176
3155
3177
- return true;
3156
+ is_dump = true;
3157
+ out :
3158
+ consume_skb (clone );
3159
+ return is_dump ;
3178
3160
}
3179
3161
3180
3162
static int btusb_recv_acl_qca (struct hci_dev * hdev , struct sk_buff * skb )
0 commit comments