@@ -966,19 +966,12 @@ cdc_ncm_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
966
966
return NULL ;
967
967
}
968
968
969
- static int cdc_ncm_rx_fixup (struct usbnet * dev , struct sk_buff * skb_in )
969
+ /* verify NTB header and return offset of first NDP, or negative error */
970
+ static int cdc_ncm_rx_verify_nth16 (struct cdc_ncm_ctx * ctx , struct sk_buff * skb_in )
970
971
{
971
- struct sk_buff * skb ;
972
- struct cdc_ncm_ctx * ctx = (struct cdc_ncm_ctx * )dev -> data [0 ];
973
- int len ;
974
- int nframes ;
975
- int x ;
976
- int offset ;
977
972
struct usb_cdc_ncm_nth16 * nth16 ;
978
- struct usb_cdc_ncm_ndp16 * ndp16 ;
979
- struct usb_cdc_ncm_dpe16 * dpe16 ;
980
- int ndpoffset ;
981
- int loopcount = 50 ; /* arbitrary max preventing infinite loop */
973
+ int len ;
974
+ int ret = - EINVAL ;
982
975
983
976
if (ctx == NULL )
984
977
goto error ;
@@ -1012,40 +1005,74 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in)
1012
1005
}
1013
1006
ctx -> rx_seq = le16_to_cpu (nth16 -> wSequence );
1014
1007
1015
- ndpoffset = le16_to_cpu (nth16 -> wNdpIndex );
1016
- next_ndp :
1008
+ ret = le16_to_cpu (nth16 -> wNdpIndex );
1009
+ error :
1010
+ return ret ;
1011
+ }
1012
+
1013
+ /* verify NDP header and return number of datagrams, or negative error */
1014
+ static int cdc_ncm_rx_verify_ndp16 (struct sk_buff * skb_in , int ndpoffset )
1015
+ {
1016
+ struct usb_cdc_ncm_ndp16 * ndp16 ;
1017
+ int ret = - EINVAL ;
1018
+
1017
1019
if ((ndpoffset + sizeof (struct usb_cdc_ncm_ndp16 )) > skb_in -> len ) {
1018
1020
pr_debug ("invalid NDP offset <%u>\n" , ndpoffset );
1019
1021
goto error ;
1020
1022
}
1021
1023
ndp16 = (struct usb_cdc_ncm_ndp16 * )(skb_in -> data + ndpoffset );
1022
1024
1023
- if (le32_to_cpu (ndp16 -> dwSignature ) != USB_CDC_NCM_NDP16_NOCRC_SIGN ) {
1024
- pr_debug ("invalid DPT16 signature <%u>\n" ,
1025
- le32_to_cpu (ndp16 -> dwSignature ));
1026
- goto err_ndp ;
1027
- }
1028
-
1029
1025
if (le16_to_cpu (ndp16 -> wLength ) < USB_CDC_NCM_NDP16_LENGTH_MIN ) {
1030
1026
pr_debug ("invalid DPT16 length <%u>\n" ,
1031
1027
le32_to_cpu (ndp16 -> dwSignature ));
1032
- goto err_ndp ;
1028
+ goto error ;
1033
1029
}
1034
1030
1035
- nframes = ((le16_to_cpu (ndp16 -> wLength ) -
1031
+ ret = ((le16_to_cpu (ndp16 -> wLength ) -
1036
1032
sizeof (struct usb_cdc_ncm_ndp16 )) /
1037
1033
sizeof (struct usb_cdc_ncm_dpe16 ));
1038
- nframes -- ; /* we process NDP entries except for the last one */
1039
-
1040
- ndpoffset += sizeof (struct usb_cdc_ncm_ndp16 );
1034
+ ret -- ; /* we process NDP entries except for the last one */
1041
1035
1042
- if ((ndpoffset + nframes * (sizeof (struct usb_cdc_ncm_dpe16 ))) >
1036
+ if ((sizeof ( struct usb_cdc_ncm_ndp16 ) + ret * (sizeof (struct usb_cdc_ncm_dpe16 ))) >
1043
1037
skb_in -> len ) {
1044
- pr_debug ("Invalid nframes = %d\n" , nframes );
1045
- goto err_ndp ;
1038
+ pr_debug ("Invalid nframes = %d\n" , ret );
1039
+ ret = - EINVAL ;
1046
1040
}
1047
1041
1048
- dpe16 = (struct usb_cdc_ncm_dpe16 * )(skb_in -> data + ndpoffset );
1042
+ error :
1043
+ return ret ;
1044
+ }
1045
+
1046
+ static int cdc_ncm_rx_fixup (struct usbnet * dev , struct sk_buff * skb_in )
1047
+ {
1048
+ struct sk_buff * skb ;
1049
+ struct cdc_ncm_ctx * ctx = (struct cdc_ncm_ctx * )dev -> data [0 ];
1050
+ int len ;
1051
+ int nframes ;
1052
+ int x ;
1053
+ int offset ;
1054
+ struct usb_cdc_ncm_ndp16 * ndp16 ;
1055
+ struct usb_cdc_ncm_dpe16 * dpe16 ;
1056
+ int ndpoffset ;
1057
+ int loopcount = 50 ; /* arbitrary max preventing infinite loop */
1058
+
1059
+ ndpoffset = cdc_ncm_rx_verify_nth16 (ctx , skb_in );
1060
+ if (ndpoffset < 0 )
1061
+ goto error ;
1062
+
1063
+ next_ndp :
1064
+ nframes = cdc_ncm_rx_verify_ndp16 (skb_in , ndpoffset );
1065
+ if (nframes < 0 )
1066
+ goto error ;
1067
+
1068
+ ndp16 = (struct usb_cdc_ncm_ndp16 * )(skb_in -> data + ndpoffset );
1069
+
1070
+ if (le32_to_cpu (ndp16 -> dwSignature ) != USB_CDC_NCM_NDP16_NOCRC_SIGN ) {
1071
+ pr_debug ("invalid DPT16 signature <%u>\n" ,
1072
+ le32_to_cpu (ndp16 -> dwSignature ));
1073
+ goto err_ndp ;
1074
+ }
1075
+ dpe16 = ndp16 -> dpe16 ;
1049
1076
1050
1077
for (x = 0 ; x < nframes ; x ++ , dpe16 ++ ) {
1051
1078
offset = le16_to_cpu (dpe16 -> wDatagramIndex );
0 commit comments