@@ -58,7 +58,7 @@ static int nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
5858 struct nci_conn_info * conn_info ;
5959 int i ;
6060
61- if (skb -> len < sizeof (struct nci_core_conn_credit_ntf ))
61+ if (skb -> len < offsetofend (struct nci_core_conn_credit_ntf , num_entries ))
6262 return - EINVAL ;
6363
6464 ntf = (struct nci_core_conn_credit_ntf * )skb -> data ;
@@ -68,6 +68,10 @@ static int nci_core_conn_credits_ntf_packet(struct nci_dev *ndev,
6868 if (ntf -> num_entries > NCI_MAX_NUM_CONN )
6969 ntf -> num_entries = NCI_MAX_NUM_CONN ;
7070
71+ if (skb -> len < offsetofend (struct nci_core_conn_credit_ntf , num_entries ) +
72+ ntf -> num_entries * sizeof (struct conn_credit_entry ))
73+ return - EINVAL ;
74+
7175 /* update the credits */
7276 for (i = 0 ; i < ntf -> num_entries ; i ++ ) {
7377 ntf -> conn_entries [i ].conn_id =
@@ -138,23 +142,48 @@ static int nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,
138142static const __u8 *
139143nci_extract_rf_params_nfca_passive_poll (struct nci_dev * ndev ,
140144 struct rf_tech_specific_params_nfca_poll * nfca_poll ,
141- const __u8 * data )
145+ const __u8 * data , ssize_t data_len )
142146{
147+ /* Check if we have enough data for sens_res (2 bytes) */
148+ if (data_len < 2 )
149+ return ERR_PTR (- EINVAL );
150+
143151 nfca_poll -> sens_res = __le16_to_cpu (* ((__le16 * )data ));
144152 data += 2 ;
153+ data_len -= 2 ;
154+
155+ /* Check if we have enough data for nfcid1_len (1 byte) */
156+ if (data_len < 1 )
157+ return ERR_PTR (- EINVAL );
145158
146159 nfca_poll -> nfcid1_len = min_t (__u8 , * data ++ , NFC_NFCID1_MAXSIZE );
160+ data_len -- ;
147161
148162 pr_debug ("sens_res 0x%x, nfcid1_len %d\n" ,
149163 nfca_poll -> sens_res , nfca_poll -> nfcid1_len );
150164
165+ /* Check if we have enough data for nfcid1 */
166+ if (data_len < nfca_poll -> nfcid1_len )
167+ return ERR_PTR (- EINVAL );
168+
151169 memcpy (nfca_poll -> nfcid1 , data , nfca_poll -> nfcid1_len );
152170 data += nfca_poll -> nfcid1_len ;
171+ data_len -= nfca_poll -> nfcid1_len ;
172+
173+ /* Check if we have enough data for sel_res_len (1 byte) */
174+ if (data_len < 1 )
175+ return ERR_PTR (- EINVAL );
153176
154177 nfca_poll -> sel_res_len = * data ++ ;
178+ data_len -- ;
179+
180+ if (nfca_poll -> sel_res_len != 0 ) {
181+ /* Check if we have enough data for sel_res (1 byte) */
182+ if (data_len < 1 )
183+ return ERR_PTR (- EINVAL );
155184
156- if (nfca_poll -> sel_res_len != 0 )
157185 nfca_poll -> sel_res = * data ++ ;
186+ }
158187
159188 pr_debug ("sel_res_len %d, sel_res 0x%x\n" ,
160189 nfca_poll -> sel_res_len ,
@@ -166,12 +195,21 @@ nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,
166195static const __u8 *
167196nci_extract_rf_params_nfcb_passive_poll (struct nci_dev * ndev ,
168197 struct rf_tech_specific_params_nfcb_poll * nfcb_poll ,
169- const __u8 * data )
198+ const __u8 * data , ssize_t data_len )
170199{
200+ /* Check if we have enough data for sensb_res_len (1 byte) */
201+ if (data_len < 1 )
202+ return ERR_PTR (- EINVAL );
203+
171204 nfcb_poll -> sensb_res_len = min_t (__u8 , * data ++ , NFC_SENSB_RES_MAXSIZE );
205+ data_len -- ;
172206
173207 pr_debug ("sensb_res_len %d\n" , nfcb_poll -> sensb_res_len );
174208
209+ /* Check if we have enough data for sensb_res */
210+ if (data_len < nfcb_poll -> sensb_res_len )
211+ return ERR_PTR (- EINVAL );
212+
175213 memcpy (nfcb_poll -> sensb_res , data , nfcb_poll -> sensb_res_len );
176214 data += nfcb_poll -> sensb_res_len ;
177215
@@ -181,14 +219,29 @@ nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev,
181219static const __u8 *
182220nci_extract_rf_params_nfcf_passive_poll (struct nci_dev * ndev ,
183221 struct rf_tech_specific_params_nfcf_poll * nfcf_poll ,
184- const __u8 * data )
222+ const __u8 * data , ssize_t data_len )
185223{
224+ /* Check if we have enough data for bit_rate (1 byte) */
225+ if (data_len < 1 )
226+ return ERR_PTR (- EINVAL );
227+
186228 nfcf_poll -> bit_rate = * data ++ ;
229+ data_len -- ;
230+
231+ /* Check if we have enough data for sensf_res_len (1 byte) */
232+ if (data_len < 1 )
233+ return ERR_PTR (- EINVAL );
234+
187235 nfcf_poll -> sensf_res_len = min_t (__u8 , * data ++ , NFC_SENSF_RES_MAXSIZE );
236+ data_len -- ;
188237
189238 pr_debug ("bit_rate %d, sensf_res_len %d\n" ,
190239 nfcf_poll -> bit_rate , nfcf_poll -> sensf_res_len );
191240
241+ /* Check if we have enough data for sensf_res */
242+ if (data_len < nfcf_poll -> sensf_res_len )
243+ return ERR_PTR (- EINVAL );
244+
192245 memcpy (nfcf_poll -> sensf_res , data , nfcf_poll -> sensf_res_len );
193246 data += nfcf_poll -> sensf_res_len ;
194247
@@ -198,22 +251,49 @@ nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev,
198251static const __u8 *
199252nci_extract_rf_params_nfcv_passive_poll (struct nci_dev * ndev ,
200253 struct rf_tech_specific_params_nfcv_poll * nfcv_poll ,
201- const __u8 * data )
254+ const __u8 * data , ssize_t data_len )
202255{
256+ /* Skip 1 byte (reserved) */
257+ if (data_len < 1 )
258+ return ERR_PTR (- EINVAL );
259+
203260 ++ data ;
261+ data_len -- ;
262+
263+ /* Check if we have enough data for dsfid (1 byte) */
264+ if (data_len < 1 )
265+ return ERR_PTR (- EINVAL );
266+
204267 nfcv_poll -> dsfid = * data ++ ;
268+ data_len -- ;
269+
270+ /* Check if we have enough data for uid (8 bytes) */
271+ if (data_len < NFC_ISO15693_UID_MAXSIZE )
272+ return ERR_PTR (- EINVAL );
273+
205274 memcpy (nfcv_poll -> uid , data , NFC_ISO15693_UID_MAXSIZE );
206275 data += NFC_ISO15693_UID_MAXSIZE ;
276+
207277 return data ;
208278}
209279
210280static const __u8 *
211281nci_extract_rf_params_nfcf_passive_listen (struct nci_dev * ndev ,
212282 struct rf_tech_specific_params_nfcf_listen * nfcf_listen ,
213- const __u8 * data )
283+ const __u8 * data , ssize_t data_len )
214284{
285+ /* Check if we have enough data for local_nfcid2_len (1 byte) */
286+ if (data_len < 1 )
287+ return ERR_PTR (- EINVAL );
288+
215289 nfcf_listen -> local_nfcid2_len = min_t (__u8 , * data ++ ,
216290 NFC_NFCID2_MAXSIZE );
291+ data_len -- ;
292+
293+ /* Check if we have enough data for local_nfcid2 */
294+ if (data_len < nfcf_listen -> local_nfcid2_len )
295+ return ERR_PTR (- EINVAL );
296+
217297 memcpy (nfcf_listen -> local_nfcid2 , data , nfcf_listen -> local_nfcid2_len );
218298 data += nfcf_listen -> local_nfcid2_len ;
219299
@@ -364,7 +444,7 @@ static int nci_rf_discover_ntf_packet(struct nci_dev *ndev,
364444 const __u8 * data ;
365445 bool add_target = true;
366446
367- if (skb -> len < sizeof (struct nci_rf_discover_ntf ))
447+ if (skb -> len < offsetofend (struct nci_rf_discover_ntf , rf_tech_specific_params_len ))
368448 return - EINVAL ;
369449
370450 data = skb -> data ;
@@ -380,26 +460,42 @@ static int nci_rf_discover_ntf_packet(struct nci_dev *ndev,
380460 pr_debug ("rf_tech_specific_params_len %d\n" ,
381461 ntf .rf_tech_specific_params_len );
382462
463+ if (skb -> len < (data - skb -> data ) +
464+ ntf .rf_tech_specific_params_len + sizeof (ntf .ntf_type ))
465+ return - EINVAL ;
466+
383467 if (ntf .rf_tech_specific_params_len > 0 ) {
384468 switch (ntf .rf_tech_and_mode ) {
385469 case NCI_NFC_A_PASSIVE_POLL_MODE :
386470 data = nci_extract_rf_params_nfca_passive_poll (ndev ,
387- & (ntf .rf_tech_specific_params .nfca_poll ), data );
471+ & (ntf .rf_tech_specific_params .nfca_poll ), data ,
472+ ntf .rf_tech_specific_params_len );
473+ if (IS_ERR (data ))
474+ return PTR_ERR (data );
388475 break ;
389476
390477 case NCI_NFC_B_PASSIVE_POLL_MODE :
391478 data = nci_extract_rf_params_nfcb_passive_poll (ndev ,
392- & (ntf .rf_tech_specific_params .nfcb_poll ), data );
479+ & (ntf .rf_tech_specific_params .nfcb_poll ), data ,
480+ ntf .rf_tech_specific_params_len );
481+ if (IS_ERR (data ))
482+ return PTR_ERR (data );
393483 break ;
394484
395485 case NCI_NFC_F_PASSIVE_POLL_MODE :
396486 data = nci_extract_rf_params_nfcf_passive_poll (ndev ,
397- & (ntf .rf_tech_specific_params .nfcf_poll ), data );
487+ & (ntf .rf_tech_specific_params .nfcf_poll ), data ,
488+ ntf .rf_tech_specific_params_len );
489+ if (IS_ERR (data ))
490+ return PTR_ERR (data );
398491 break ;
399492
400493 case NCI_NFC_V_PASSIVE_POLL_MODE :
401494 data = nci_extract_rf_params_nfcv_passive_poll (ndev ,
402- & (ntf .rf_tech_specific_params .nfcv_poll ), data );
495+ & (ntf .rf_tech_specific_params .nfcv_poll ), data ,
496+ ntf .rf_tech_specific_params_len );
497+ if (IS_ERR (data ))
498+ return PTR_ERR (data );
403499 break ;
404500
405501 default :
@@ -596,7 +692,7 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
596692 const __u8 * data ;
597693 int err = NCI_STATUS_OK ;
598694
599- if (skb -> len < sizeof (struct nci_rf_intf_activated_ntf ))
695+ if (skb -> len < offsetofend (struct nci_rf_intf_activated_ntf , rf_tech_specific_params_len ))
600696 return - EINVAL ;
601697
602698 data = skb -> data ;
@@ -628,26 +724,41 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
628724 if (ntf .rf_interface == NCI_RF_INTERFACE_NFCEE_DIRECT )
629725 goto listen ;
630726
727+ if (skb -> len < (data - skb -> data ) + ntf .rf_tech_specific_params_len )
728+ return - EINVAL ;
729+
631730 if (ntf .rf_tech_specific_params_len > 0 ) {
632731 switch (ntf .activation_rf_tech_and_mode ) {
633732 case NCI_NFC_A_PASSIVE_POLL_MODE :
634733 data = nci_extract_rf_params_nfca_passive_poll (ndev ,
635- & (ntf .rf_tech_specific_params .nfca_poll ), data );
734+ & (ntf .rf_tech_specific_params .nfca_poll ), data ,
735+ ntf .rf_tech_specific_params_len );
736+ if (IS_ERR (data ))
737+ return - EINVAL ;
636738 break ;
637739
638740 case NCI_NFC_B_PASSIVE_POLL_MODE :
639741 data = nci_extract_rf_params_nfcb_passive_poll (ndev ,
640- & (ntf .rf_tech_specific_params .nfcb_poll ), data );
742+ & (ntf .rf_tech_specific_params .nfcb_poll ), data ,
743+ ntf .rf_tech_specific_params_len );
744+ if (IS_ERR (data ))
745+ return - EINVAL ;
641746 break ;
642747
643748 case NCI_NFC_F_PASSIVE_POLL_MODE :
644749 data = nci_extract_rf_params_nfcf_passive_poll (ndev ,
645- & (ntf .rf_tech_specific_params .nfcf_poll ), data );
750+ & (ntf .rf_tech_specific_params .nfcf_poll ), data ,
751+ ntf .rf_tech_specific_params_len );
752+ if (IS_ERR (data ))
753+ return - EINVAL ;
646754 break ;
647755
648756 case NCI_NFC_V_PASSIVE_POLL_MODE :
649757 data = nci_extract_rf_params_nfcv_passive_poll (ndev ,
650- & (ntf .rf_tech_specific_params .nfcv_poll ), data );
758+ & (ntf .rf_tech_specific_params .nfcv_poll ), data ,
759+ ntf .rf_tech_specific_params_len );
760+ if (IS_ERR (data ))
761+ return - EINVAL ;
651762 break ;
652763
653764 case NCI_NFC_A_PASSIVE_LISTEN_MODE :
@@ -657,7 +768,9 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
657768 case NCI_NFC_F_PASSIVE_LISTEN_MODE :
658769 data = nci_extract_rf_params_nfcf_passive_listen (ndev ,
659770 & (ntf .rf_tech_specific_params .nfcf_listen ),
660- data );
771+ data , ntf .rf_tech_specific_params_len );
772+ if (IS_ERR (data ))
773+ return - EINVAL ;
661774 break ;
662775
663776 default :
@@ -668,6 +781,13 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
668781 }
669782 }
670783
784+ if (skb -> len < (data - skb -> data ) +
785+ sizeof (ntf .data_exch_rf_tech_and_mode ) +
786+ sizeof (ntf .data_exch_tx_bit_rate ) +
787+ sizeof (ntf .data_exch_rx_bit_rate ) +
788+ sizeof (ntf .activation_params_len ))
789+ return - EINVAL ;
790+
671791 ntf .data_exch_rf_tech_and_mode = * data ++ ;
672792 ntf .data_exch_tx_bit_rate = * data ++ ;
673793 ntf .data_exch_rx_bit_rate = * data ++ ;
@@ -679,6 +799,9 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev,
679799 pr_debug ("data_exch_rx_bit_rate 0x%x\n" , ntf .data_exch_rx_bit_rate );
680800 pr_debug ("activation_params_len %d\n" , ntf .activation_params_len );
681801
802+ if (skb -> len < (data - skb -> data ) + ntf .activation_params_len )
803+ return - EINVAL ;
804+
682805 if (ntf .activation_params_len > 0 ) {
683806 switch (ntf .rf_interface ) {
684807 case NCI_RF_INTERFACE_ISO_DEP :
0 commit comments