@@ -1181,12 +1181,15 @@ static int ncm_unwrap_ntb(struct gether *port,
11811181int ndp_index ;
11821182unsigned dg_len ,dg_len2 ;
11831183unsigned ndp_len ;
1184+ unsigned block_len ;
11841185struct sk_buff * skb2 ;
11851186int ret = - EINVAL ;
1186- unsigned max_size = le32_to_cpu (ntb_parameters .dwNtbOutMaxSize );
1187+ unsigned ntb_max = le32_to_cpu (ntb_parameters .dwNtbOutMaxSize );
1188+ unsigned frame_max = le16_to_cpu (ecm_desc .wMaxSegmentSize );
11871189const struct ndp_parser_opts * opts = ncm -> parser_opts ;
11881190unsigned crc_len = ncm -> is_crc ?sizeof (uint32_t ) :0 ;
11891191int dgram_counter ;
1192+ bool ndp_after_header ;
11901193
11911194/* dwSignature */
11921195if (get_unaligned_le32 (tmp )!= opts -> nth_sign ) {
@@ -1205,25 +1208,37 @@ static int ncm_unwrap_ntb(struct gether *port,
12051208}
12061209tmp ++ ;/* skip wSequence */
12071210
1211+ block_len = get_ncm (& tmp ,opts -> block_length );
12081212/* (d)wBlockLength */
1209- if (get_ncm ( & tmp , opts -> block_length ) > max_size ) {
1213+ if (block_len > ntb_max ) {
12101214INFO (port -> func .config -> cdev ,"OUT size exceeded\n" );
12111215gotoerr ;
12121216}
12131217
12141218ndp_index = get_ncm (& tmp ,opts -> ndp_index );
1219+ ndp_after_header = false;
12151220
12161221/* Run through all the NDP's in the NTB */
12171222do {
1218- /* NCM 3.2 */
1219- if (((ndp_index %4 )!= 0 )&&
1220- (ndp_index < opts -> nth_size )) {
1223+ /*
1224+ * NCM 3.2
1225+ * dwNdpIndex
1226+ */
1227+ if (((ndp_index %4 )!= 0 )||
1228+ (ndp_index < opts -> nth_size )||
1229+ (ndp_index > (block_len -
1230+ opts -> ndp_size ))) {
12211231INFO (port -> func .config -> cdev ,"Bad index: %#X\n" ,
12221232ndp_index );
12231233gotoerr ;
12241234}
1235+ if (ndp_index == opts -> nth_size )
1236+ ndp_after_header = true;
12251237
1226- /* walk through NDP */
1238+ /*
1239+ * walk through NDP
1240+ * dwSignature
1241+ */
12271242tmp = (void * )(skb -> data + ndp_index );
12281243if (get_unaligned_le32 (tmp )!= ncm -> ndp_sign ) {
12291244INFO (port -> func .config -> cdev ,"Wrong NDP SIGN\n" );
@@ -1234,14 +1249,15 @@ static int ncm_unwrap_ntb(struct gether *port,
12341249ndp_len = get_unaligned_le16 (tmp ++ );
12351250/*
12361251 * NCM 3.3.1
1252+ * wLength
12371253 * entry is 2 items
12381254 * item size is 16/32 bits, opts->dgram_item_len * 2 bytes
12391255 * minimal: struct usb_cdc_ncm_ndpX + normal entry + zero entry
12401256 * Each entry is a dgram index and a dgram length.
12411257 */
12421258if ((ndp_len < opts -> ndp_size
1243- + 2 * 2 * (opts -> dgram_item_len * 2 ))
1244- || (ndp_len %opts -> ndplen_align != 0 )) {
1259+ + 2 * 2 * (opts -> dgram_item_len * 2 ))||
1260+ (ndp_len %opts -> ndplen_align != 0 )) {
12451261INFO (port -> func .config -> cdev ,"Bad NDP length: %#X\n" ,
12461262ndp_len );
12471263gotoerr ;
@@ -1258,8 +1274,21 @@ static int ncm_unwrap_ntb(struct gether *port,
12581274
12591275do {
12601276index = index2 ;
1277+ /* wDatagramIndex[0] */
1278+ if ((index < opts -> nth_size )||
1279+ (index > block_len - opts -> dpe_size )) {
1280+ INFO (port -> func .config -> cdev ,
1281+ "Bad index: %#X\n" ,index );
1282+ gotoerr ;
1283+ }
1284+
12611285dg_len = dg_len2 ;
1262- if (dg_len < 14 + crc_len ) {/* ethernet hdr + crc */
1286+ /*
1287+ * wDatagramLength[0]
1288+ * ethernet hdr + crc or larger than max frame size
1289+ */
1290+ if ((dg_len < 14 + crc_len )||
1291+ (dg_len > frame_max )) {
12631292INFO (port -> func .config -> cdev ,
12641293"Bad dgram length: %#X\n" ,dg_len );
12651294gotoerr ;
@@ -1283,6 +1312,37 @@ static int ncm_unwrap_ntb(struct gether *port,
12831312index2 = get_ncm (& tmp ,opts -> dgram_item_len );
12841313dg_len2 = get_ncm (& tmp ,opts -> dgram_item_len );
12851314
1315+ if (index2 == 0 || dg_len2 == 0 )
1316+ break ;
1317+
1318+ /* wDatagramIndex[1] */
1319+ if (ndp_after_header ) {
1320+ if (index2 < opts -> nth_size + opts -> ndp_size ) {
1321+ INFO (port -> func .config -> cdev ,
1322+ "Bad index: %#X\n" ,index2 );
1323+ gotoerr ;
1324+ }
1325+ }else {
1326+ if (index2 < opts -> nth_size + opts -> dpe_size ) {
1327+ INFO (port -> func .config -> cdev ,
1328+ "Bad index: %#X\n" ,index2 );
1329+ gotoerr ;
1330+ }
1331+ }
1332+ if (index2 > block_len - opts -> dpe_size ) {
1333+ INFO (port -> func .config -> cdev ,
1334+ "Bad index: %#X\n" ,index2 );
1335+ gotoerr ;
1336+ }
1337+
1338+ /* wDatagramLength[1] */
1339+ if ((dg_len2 < 14 + crc_len )||
1340+ (dg_len2 > frame_max )) {
1341+ INFO (port -> func .config -> cdev ,
1342+ "Bad dgram length: %#X\n" ,dg_len );
1343+ gotoerr ;
1344+ }
1345+
12861346/*
12871347 * Copy the data into a new skb.
12881348 * This ensures the truesize is correct
@@ -1299,9 +1359,6 @@ static int ncm_unwrap_ntb(struct gether *port,
12991359ndp_len -= 2 * (opts -> dgram_item_len * 2 );
13001360
13011361dgram_counter ++ ;
1302-
1303- if (index2 == 0 || dg_len2 == 0 )
1304- break ;
13051362}while (ndp_len > 2 * (opts -> dgram_item_len * 2 ));
13061363}while (ndp_index );
13071364